/// <summary> /// Creates a fully populated message with a consistent set of /// test data. /// </summary> /// /// <returns>The populated message.</returns> /// private static AmqpAnnotatedMessage CreateEmptydDataBodyMessage() { var body = AmqpMessageBody.FromData(new[] { (ReadOnlyMemory <byte>)Array.Empty <byte>() }); var message = new AmqpAnnotatedMessage(body); return(message); }
public void MessageIsPopulatedFromEventHubProperties() { var properties = new Dictionary <string, object> { { "Test", 1 }, { "Second", "2" }, { "Third", TimeSpan.FromSeconds(99) } }; var sequenceNumber = 123L; var offset = 456L; var enqueueTime = new DateTimeOffset(2015, 10, 27, 00, 00, 00, TimeSpan.Zero); var partitionKey = "fake-key"; var lastSequence = 321L; var lastOffset = 654L; var lastEnqueue = new DateTimeOffset(2012, 03, 04, 08, 00, 00, TimeSpan.Zero); var lastRetrieve = new DateTimeOffset(2020, 01, 01, 05, 15, 37, TimeSpan.Zero); var message = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(new[] { (ReadOnlyMemory <byte>)Array.Empty <byte>() })); message.PopulateFromEventProperties(properties, sequenceNumber, offset, enqueueTime, partitionKey, lastSequence, lastOffset, lastEnqueue, lastRetrieve); Assert.That(message.ApplicationProperties, Is.EquivalentTo(properties), "The application properties should match."); Assert.That(message.GetSequenceNumber(), Is.EqualTo(sequenceNumber), "The sequence number should match."); Assert.That(message.GetOffset(), Is.EqualTo(offset), "The offset should match."); Assert.That(message.GetEnqueuedTime(), Is.EqualTo(enqueueTime), "The enqueue time should match."); Assert.That(message.GetPartitionKey(), Is.EqualTo(partitionKey), "The partition key should match."); Assert.That(message.GetLastPartitionSequenceNumber(), Is.EqualTo(lastSequence), "The last sequence number should match."); Assert.That(message.GetLastPartitionOffset(), Is.EqualTo(lastOffset), "The last offset should match."); Assert.That(message.GetLastPartitionEnqueuedTime(), Is.EqualTo(lastEnqueue), "The last enqueue time should match."); Assert.That(message.GetLastPartitionPropertiesRetrievalTime(), Is.EqualTo(lastRetrieve), "The last retrieve time should match."); }
/// <summary> /// Creates a fully populated message with a consistent set of /// test data and the specified set of system properties. /// </summary> /// /// <param name="sequenceNumber">The sequence number of the event; if null, this will not be populated.</param> /// <param name="lastSequenceNumber">The sequence number that was last enqueued in the partition; if null, this will not be populated.</param> /// <param name="offset">The offset of the event; if null, this will not be populated.</param> /// <param name="lastOffset">The offset that was last enqueued in the partition; if null, this will not be populated.</param> /// <param name="partitionKey">The partition key of the event; if null, this will not be populated.</param> /// <param name="enqueueTime">The time that the event was enqueued in the partition; if null, this will not be populated.</param> /// <param name="lastEnqueueTime">The time that an event was last enqueued in the partition; if null, this will not be populated.</param> /// <param name="lastRetrieveTime">The time that the information about the last event enqueued in the partition was reported; if null, this will not be populated.</param> /// /// <returns>The populated message.</returns> /// private static AmqpAnnotatedMessage CreateFullyPopulatedAmqpMessage(long sequenceNumber, long lastSequenceNumber, long offset, long lastOffset, string partitionKey, DateTimeOffset enqueueTime, DateTimeOffset lastEnqueueTime, DateTimeOffset lastRetrieveTime) { var body = AmqpMessageBody.FromData(new ReadOnlyMemory <byte>[] { new byte[] { 0x65, 0x66, 0x67, 0x68 } }); var message = new AmqpAnnotatedMessage(body); // Header message.Header.DeliveryCount = 99; message.Header.Durable = true; message.Header.FirstAcquirer = true; message.Header.Priority = 123; message.Header.TimeToLive = TimeSpan.FromSeconds(10); // Properties message.Properties.AbsoluteExpiryTime = new DateTimeOffset(2015, 10, 27, 00, 00, 00, TimeSpan.Zero); message.Properties.ContentEncoding = "fake"; message.Properties.ContentType = "test/unit"; message.Properties.CorrelationId = new AmqpMessageId("red-5"); message.Properties.CreationTime = new DateTimeOffset(2012, 03, 04, 08, 00, 00, 00, TimeSpan.Zero); message.Properties.GroupId = "mine!"; message.Properties.GroupSequence = 555; message.Properties.MessageId = new AmqpMessageId("red-leader"); message.Properties.ReplyTo = new AmqpAddress("amqps://some.namespace.com"); message.Properties.ReplyToGroupId = "not-mine!"; message.Properties.Subject = "We tried to copy an AMQP message. You won't believe what happened next!"; message.Properties.To = new AmqpAddress("https://some.url.com"); message.Properties.UserId = new byte[] { 0x11, 0x22 }; // Application Properties message.ApplicationProperties.Add("first", 1); message.ApplicationProperties.Add("second", "two"); // Message Annotations message.MessageAnnotations.Add(AmqpProperty.SequenceNumber.ToString(), sequenceNumber); message.MessageAnnotations.Add(AmqpProperty.Offset.ToString(), offset); message.MessageAnnotations.Add(AmqpProperty.EnqueuedTime.ToString(), enqueueTime); message.MessageAnnotations.Add(AmqpProperty.PartitionKey.ToString(), partitionKey); // Delivery annotations message.DeliveryAnnotations.Add(AmqpProperty.PartitionLastEnqueuedSequenceNumber.ToString(), lastSequenceNumber); message.DeliveryAnnotations.Add(AmqpProperty.PartitionLastEnqueuedOffset.ToString(), lastOffset); message.DeliveryAnnotations.Add(AmqpProperty.PartitionLastEnqueuedTimeUtc.ToString(), lastEnqueueTime); message.DeliveryAnnotations.Add(AmqpProperty.LastPartitionPropertiesRetrievalTimeUtc.ToString(), lastRetrieveTime); return(message); }
public void GetEventBodyRetrievesTheDataBody() { var payload = new byte[] { 0x10, 0x20, 0x30 }; var body = AmqpMessageBody.FromData(new ReadOnlyMemory <byte>[1] { payload }); var message = new AmqpAnnotatedMessage(body); var eventBody = message.GetEventBody(); Assert.That(eventBody, Is.Not.Null, "The event body should be populated."); Assert.That(eventBody.ToArray(), Is.EquivalentTo(payload), "The event body should match the original payload."); }
/// <summary> /// Creates a fully populated message with a consistent set of /// test data. /// </summary> /// /// <returns>The populated message.</returns> /// private static AmqpAnnotatedMessage CreatePopulatedDataBodyMessage() { var body = AmqpMessageBody.FromData(new[] { (ReadOnlyMemory <byte>)Array.Empty <byte>() }); var message = new AmqpAnnotatedMessage(body); // Header message.Header.DeliveryCount = 99; message.Header.Durable = true; message.Header.FirstAcquirer = true; message.Header.Priority = 123; message.Header.TimeToLive = TimeSpan.FromSeconds(10); // Properties message.Properties.AbsoluteExpiryTime = new DateTimeOffset(2015, 10, 27, 00, 00, 00, TimeSpan.Zero); message.Properties.ContentEncoding = "fake"; message.Properties.ContentType = "test/unit"; message.Properties.CorrelationId = new AmqpMessageId("red-5"); message.Properties.CreationTime = new DateTimeOffset(2012, 03, 04, 08, 00, 00, 00, TimeSpan.Zero); message.Properties.GroupId = "mine!"; message.Properties.GroupSequence = 555; message.Properties.MessageId = new AmqpMessageId("red-leader"); message.Properties.ReplyTo = new AmqpAddress("amqps://some.namespace.com"); message.Properties.ReplyToGroupId = "not-mine!"; message.Properties.Subject = "We tried to copy an AMQP message. You won't believe what happened next!"; message.Properties.To = new AmqpAddress("https://some.url.com"); message.Properties.UserId = new byte[] { 0x11, 0x22 }; // Footer message.Footer.Add("one", "1111"); message.Footer.Add("two", "2222"); // Delivery Annotations message.DeliveryAnnotations.Add("three", "3333"); // Message Annotations message.MessageAnnotations.Add("four", "4444"); message.MessageAnnotations.Add("five", "5555"); message.MessageAnnotations.Add("six", "6666"); // Application Properties message.ApplicationProperties.Add("seven", "7777"); return(message); }
public void ReadingUnpopulatedMutablePropertiesDoesNotCreateTheSection() { var amqpMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(new[] { ReadOnlyMemory <byte> .Empty })); var eventData = new EventData(amqpMessage); Assert.That(eventData.MessageId, Is.Null, "The message identifier should not be populated."); Assert.That(amqpMessage.HasSection(AmqpMessageSection.Properties), Is.False, "Reading the message identifier should not create the section."); Assert.That(eventData.CorrelationId, Is.Null, "The correlation identifier should not be populated."); Assert.That(amqpMessage.HasSection(AmqpMessageSection.Properties), Is.False, "Reading the correlation identifier should not create the section."); Assert.That(eventData.ContentType, Is.Null, "The content type should not be populated."); Assert.That(amqpMessage.HasSection(AmqpMessageSection.Properties), Is.False, "Reading the content type should not create the section."); }
public void CannotCreateFromNullBody() { Assert.That( () => AmqpMessageBody.FromData(data: null), Throws.InstanceOf <ArgumentNullException>()); Assert.That( () => AmqpMessageBody.FromValue(value: null), Throws.InstanceOf <ArgumentNullException>()); Assert.That( () => AmqpMessageBody.FromSequence(sequence: null), Throws.InstanceOf <ArgumentNullException>()); }
public void CanCreateDataBodyFactory() { var body = AmqpMessageBody.FromData(Array.Empty <ReadOnlyMemory <byte> >()); Assert.AreEqual(AmqpMessageBodyType.Data, body.BodyType); Assert.IsTrue(body.TryGetData(out var data)); Assert.NotNull(data); Assert.IsFalse(body.TryGetValue(out var value)); Assert.IsNull(value); Assert.IsFalse(body.TryGetSequence(out var sequence)); Assert.IsNull(sequence); }
public void MutablePropertySettersPopulateTheAmqpMessage() { var messageId = "message-id-value"; var correlationId = "correlation-id-value"; var contentType = "text/content-type"; var amqpMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(new[] { ReadOnlyMemory <byte> .Empty })); var eventData = new EventData(amqpMessage); eventData.MessageId = messageId; Assert.That(amqpMessage.Properties.MessageId.ToString(), Is.EqualTo(messageId), "The AMQP message identifier should match."); eventData.CorrelationId = correlationId; Assert.That(amqpMessage.Properties.CorrelationId.ToString(), Is.EqualTo(correlationId), "The AMQP message correlation identifier should match."); eventData.ContentType = contentType; Assert.That(amqpMessage.Properties.ContentType, Is.EqualTo(contentType), "The AMQP message content type should match."); }
/// <summary> /// Initializes a new instance of the <see cref="EventData"/> class. /// </summary> /// /// <param name="eventBody">The raw data as binary to use as the body of the event.</param> /// <param name="properties">The set of free-form event properties to send with the event.</param> /// <param name="systemProperties">The set of system properties received from the Event Hubs service.</param> /// <param name="sequenceNumber">The sequence number assigned to the event when it was enqueued in the associated Event Hub partition.</param> /// <param name="offset">The offset of the event when it was received from the associated Event Hub partition.</param> /// <param name="enqueuedTime">The date and time, in UTC, of when the event was enqueued in the Event Hub partition.</param> /// <param name="partitionKey">The partition hashing key applied to the batch that the associated <see cref="EventData"/>, was sent with.</param> /// <param name="lastPartitionSequenceNumber">The sequence number that was last enqueued into the Event Hub partition.</param> /// <param name="lastPartitionOffset">The offset that was last enqueued into the Event Hub partition.</param> /// <param name="lastPartitionEnqueuedTime">The date and time, in UTC, of the event that was last enqueued into the Event Hub partition.</param> /// <param name="lastPartitionPropertiesRetrievalTime">The date and time, in UTC, that the last event information for the Event Hub partition was retrieved from the service.</param> /// <param name="publishedSequenceNumber">The publishing sequence number assigned to the event at the time it was successfully published.</param> /// <param name="pendingPublishSequenceNumber">The publishing sequence number assigned to the event as part of a publishing operation.</param> /// <param name="pendingProducerGroupId">The producer group identifier assigned to the event as part of a publishing operation.</param> /// <param name="pendingOwnerLevel">The producer owner level assigned to the event as part of a publishing operation.</param> /// internal EventData(BinaryData eventBody, IDictionary <string, object> properties = null, IReadOnlyDictionary <string, object> systemProperties = null, long?sequenceNumber = null, long?offset = null, DateTimeOffset?enqueuedTime = null, string partitionKey = null, long?lastPartitionSequenceNumber = null, long?lastPartitionOffset = null, DateTimeOffset?lastPartitionEnqueuedTime = null, DateTimeOffset?lastPartitionPropertiesRetrievalTime = null, int?publishedSequenceNumber = null, int?pendingPublishSequenceNumber = null, long?pendingProducerGroupId = null, short?pendingOwnerLevel = null) { Argument.AssertNotNull(eventBody, nameof(eventBody)); _amqpMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(MessageBody.FromReadOnlyMemorySegment(eventBody.ToMemory()))); _amqpMessage.PopulateFromEventProperties( properties, sequenceNumber, offset, enqueuedTime, partitionKey, lastPartitionSequenceNumber, lastPartitionOffset, lastPartitionEnqueuedTime, lastPartitionPropertiesRetrievalTime); // If there was a set of system properties explicitly provided, then // override the default projection with them. if (systemProperties != null) { _systemProperties = systemProperties; } // Set the idempotent publishing state. PublishedSequenceNumber = publishedSequenceNumber; PendingPublishSequenceNumber = pendingPublishSequenceNumber; PendingProducerGroupId = pendingProducerGroupId; PendingProducerOwnerLevel = pendingOwnerLevel; }
public async Task CanSendMultipleDataSections() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); var sender = client.CreateSender(scope.QueueName); var msg = new ServiceBusMessage(); var amqp = new AmqpAnnotatedMessage( AmqpMessageBody.FromData( new ReadOnlyMemory <byte>[] { new ReadOnlyMemory <byte>(GetRandomBuffer(100)), new ReadOnlyMemory <byte>(GetRandomBuffer(100)) })); msg.AmqpMessage = amqp; await sender.SendMessageAsync(msg); var receiver = client.CreateReceiver(scope.QueueName); var received = await receiver.ReceiveMessageAsync(); received.GetRawAmqpMessage().Body.TryGetData(out var receivedData); var bodyEnum = receivedData.GetEnumerator(); int ct = 0; msg.GetRawAmqpMessage().Body.TryGetData(out var sentData); foreach (ReadOnlyMemory <byte> data in sentData) { bodyEnum.MoveNext(); var bytes = data.ToArray(); Assert.AreEqual(bytes, bodyEnum.Current.ToArray()); if (ct++ == 0) { Assert.AreEqual(bytes, received.Body.ToMemory().Slice(0, 100).ToArray()); } else { Assert.AreEqual(bytes, received.Body.ToMemory().Slice(100, 100).ToArray()); } } } }
/// <summary> /// Creates a new message from the specified received message by copying the properties. /// </summary> /// <param name="receivedMessage">The received message to copy the data from.</param> public ServiceBusMessage(ServiceBusReceivedMessage receivedMessage) { Argument.AssertNotNull(receivedMessage, nameof(receivedMessage)); AmqpMessageBody body = null; if (receivedMessage.AmqpMessage.Body.TryGetData(out IEnumerable <ReadOnlyMemory <byte> > dataBody)) { body = AmqpMessageBody.FromData(MessageBody.FromReadOnlyMemorySegments(dataBody)); } else if (receivedMessage.AmqpMessage.Body.TryGetValue(out object valueBody)) { body = AmqpMessageBody.FromValue(valueBody); } else if (receivedMessage.AmqpMessage.Body.TryGetSequence(out IEnumerable <IList <object> > sequenceBody)) { body = AmqpMessageBody.FromSequence(sequenceBody); } else { throw new NotSupportedException($"{receivedMessage.AmqpMessage.Body.BodyType} is not a supported message body type."); } AmqpMessage = new AmqpAnnotatedMessage(body); // copy properties AmqpMessageProperties properties = AmqpMessage.Properties; AmqpMessageProperties receivedProperties = receivedMessage.AmqpMessage.Properties; properties.MessageId = receivedProperties.MessageId; properties.UserId = receivedProperties.UserId; properties.To = receivedProperties.To; properties.Subject = receivedProperties.Subject; properties.ReplyTo = receivedProperties.ReplyTo; properties.CorrelationId = receivedProperties.CorrelationId; properties.ContentType = receivedProperties.ContentType; properties.ContentEncoding = receivedProperties.ContentEncoding; properties.AbsoluteExpiryTime = receivedProperties.AbsoluteExpiryTime; properties.CreationTime = receivedProperties.CreationTime; properties.GroupId = receivedProperties.GroupId; properties.GroupSequence = receivedProperties.GroupSequence; properties.ReplyToGroupId = receivedProperties.ReplyToGroupId; // copy header except for delivery count which should be set to null AmqpMessageHeader header = AmqpMessage.Header; AmqpMessageHeader receivedHeader = receivedMessage.AmqpMessage.Header; header.DeliveryCount = null; header.Durable = receivedHeader.Durable; header.Priority = receivedHeader.Priority; header.TimeToLive = receivedHeader.TimeToLive; header.FirstAcquirer = receivedHeader.FirstAcquirer; // copy message annotations except for broker set ones foreach (KeyValuePair <string, object> kvp in receivedMessage.AmqpMessage.MessageAnnotations) { if (kvp.Key == AmqpMessageConstants.LockedUntilName || kvp.Key == AmqpMessageConstants.SequenceNumberName || kvp.Key == AmqpMessageConstants.DeadLetterSourceName || kvp.Key == AmqpMessageConstants.EnqueueSequenceNumberName || kvp.Key == AmqpMessageConstants.EnqueuedTimeUtcName || kvp.Key == AmqpMessageConstants.MessageStateName) { continue; } AmqpMessage.MessageAnnotations.Add(kvp.Key, kvp.Value); } // copy delivery annotations foreach (KeyValuePair <string, object> kvp in receivedMessage.AmqpMessage.DeliveryAnnotations) { AmqpMessage.DeliveryAnnotations.Add(kvp.Key, kvp.Value); } // copy footer foreach (KeyValuePair <string, object> kvp in receivedMessage.AmqpMessage.Footer) { AmqpMessage.Footer.Add(kvp.Key, kvp.Value); } // copy application properties except for broker set ones foreach (KeyValuePair <string, object> kvp in receivedMessage.AmqpMessage.ApplicationProperties) { if (kvp.Key == AmqpMessageConstants.DeadLetterReasonHeader || kvp.Key == AmqpMessageConstants.DeadLetterErrorDescriptionHeader) { continue; } AmqpMessage.ApplicationProperties.Add(kvp.Key, kvp.Value); } }
public static ServiceBusReceivedMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false) { Argument.AssertNotNull(amqpMessage, nameof(amqpMessage)); AmqpAnnotatedMessage annotatedMessage; if ((amqpMessage.BodyType & SectionFlag.Data) != 0 && amqpMessage.DataBody != null) { annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(BodyMemory.FromAmqpData(amqpMessage.DataBody))); } else if ((amqpMessage.BodyType & SectionFlag.AmqpValue) != 0 && amqpMessage.ValueBody?.Value != null) { if (TryGetNetObjectFromAmqpObject(amqpMessage.ValueBody.Value, MappingType.MessageBody, out object netObject)) { annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromValue(netObject)); } else { throw new NotSupportedException(Resources.InvalidAmqpMessageValueBody.FormatForUser(amqpMessage.ValueBody.Value.GetType())); } } else if ((amqpMessage.BodyType & SectionFlag.AmqpSequence) != 0) { annotatedMessage = new AmqpAnnotatedMessage( AmqpMessageBody.FromSequence(amqpMessage.SequenceBody.Select(s => (IList <object>)s.List).ToList())); } // default to using an empty Data section if no data else { annotatedMessage = new AmqpAnnotatedMessage(new AmqpMessageBody(Enumerable.Empty <ReadOnlyMemory <byte> >())); } ServiceBusReceivedMessage sbMessage = new ServiceBusReceivedMessage(annotatedMessage); SectionFlag sections = amqpMessage.Sections; if ((sections & SectionFlag.Header) != 0) { if (amqpMessage.Header.Ttl != null) { annotatedMessage.Header.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value); } if (amqpMessage.Header.DeliveryCount != null) { annotatedMessage.Header.DeliveryCount = isPeeked ? (amqpMessage.Header.DeliveryCount.Value) : (amqpMessage.Header.DeliveryCount.Value + 1); } } if ((sections & SectionFlag.Properties) != 0) { if (amqpMessage.Properties.MessageId != null) { annotatedMessage.Properties.MessageId = new AmqpMessageId(amqpMessage.Properties.MessageId.ToString()); } if (amqpMessage.Properties.CorrelationId != null) { annotatedMessage.Properties.CorrelationId = new AmqpMessageId(amqpMessage.Properties.CorrelationId.ToString()); } if (amqpMessage.Properties.ContentType.Value != null) { annotatedMessage.Properties.ContentType = amqpMessage.Properties.ContentType.Value; } if (amqpMessage.Properties.Subject != null) { annotatedMessage.Properties.Subject = amqpMessage.Properties.Subject; } if (amqpMessage.Properties.To != null) { annotatedMessage.Properties.To = new AmqpAddress(amqpMessage.Properties.To.ToString()); } if (amqpMessage.Properties.ReplyTo != null) { annotatedMessage.Properties.ReplyTo = new AmqpAddress(amqpMessage.Properties.ReplyTo.ToString()); } if (amqpMessage.Properties.GroupId != null) { annotatedMessage.Properties.GroupId = amqpMessage.Properties.GroupId; } if (amqpMessage.Properties.ReplyToGroupId != null) { annotatedMessage.Properties.ReplyToGroupId = amqpMessage.Properties.ReplyToGroupId; } } // Do application properties before message annotations, because the application properties // can be updated by entries from message annotation. if ((sections & SectionFlag.ApplicationProperties) != 0) { foreach (var pair in amqpMessage.ApplicationProperties.Map) { if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject)) { annotatedMessage.ApplicationProperties[pair.Key.ToString()] = netObject; } } } if ((sections & SectionFlag.MessageAnnotations) != 0) { foreach (var pair in amqpMessage.MessageAnnotations.Map) { var key = pair.Key.ToString(); switch (key) { case AmqpMessageConstants.EnqueuedTimeUtcName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueuedTimeUtcName] = pair.Value; break; case AmqpMessageConstants.ScheduledEnqueueTimeUtcName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.ScheduledEnqueueTimeUtcName] = pair.Value; break; case AmqpMessageConstants.SequenceNumberName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.SequenceNumberName] = pair.Value; break; case AmqpMessageConstants.EnqueueSequenceNumberName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueueSequenceNumberName] = pair.Value; break; case AmqpMessageConstants.LockedUntilName: DateTimeOffset lockedUntil = (DateTime)pair.Value >= DateTimeOffset.MaxValue.UtcDateTime ? DateTimeOffset.MaxValue : (DateTime)pair.Value; annotatedMessage.MessageAnnotations[AmqpMessageConstants.LockedUntilName] = lockedUntil.UtcDateTime; break; case AmqpMessageConstants.PartitionKeyName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionKeyName] = pair.Value; break; case AmqpMessageConstants.PartitionIdName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionIdName] = pair.Value; break; case AmqpMessageConstants.ViaPartitionKeyName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.ViaPartitionKeyName] = pair.Value; break; case AmqpMessageConstants.DeadLetterSourceName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.DeadLetterSourceName] = pair.Value; break; default: if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject)) { annotatedMessage.MessageAnnotations[key] = netObject; } break; } } } if (amqpMessage.DeliveryTag.Count == GuidSizeInBytes) { Span <byte> guidBytes = stackalloc byte[GuidSizeInBytes]; amqpMessage.DeliveryTag.AsSpan().CopyTo(guidBytes); if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var lockTokenGuid)) { lockTokenGuid = new Guid(guidBytes.ToArray()); } sbMessage.LockTokenGuid = lockTokenGuid; } amqpMessage.Dispose(); return(sbMessage); }