public void ApplicationPropertiesAreCreatedOnDemand() { var message = new AmqpAnnotatedMessage(EmptyDataBody); Assert.False(message.HasSection(AmqpMessageSection.ApplicationProperties)); message.ApplicationProperties.Add("test", new object()); Assert.True(message.HasSection(AmqpMessageSection.ApplicationProperties)); Assert.NotNull(message.ApplicationProperties); }
public void FooterIsCreatedOnDemand() { var message = new AmqpAnnotatedMessage(EmptyDataBody); Assert.False(message.HasSection(AmqpMessageSection.Footer)); message.Footer.Add("test", new object()); Assert.True(message.HasSection(AmqpMessageSection.Footer)); Assert.NotNull(message.Footer); }
public void PropertiesAreCreatedOnDemand() { var message = new AmqpAnnotatedMessage(EmptyDataBody); Assert.False(message.HasSection(AmqpMessageSection.Properties)); message.Properties.ContentType = "test/unit"; Assert.True(message.HasSection(AmqpMessageSection.Properties)); Assert.NotNull(message.Properties); }
public void CanCreateAnnotatedMessage() { var message = new AmqpAnnotatedMessage(new AmqpMessageBody(new ReadOnlyMemory <byte>[] { Encoding.UTF8.GetBytes("some data") })); message.ApplicationProperties.Add("applicationKey", "applicationValue"); message.DeliveryAnnotations.Add("deliveryKey", "deliveryValue"); message.MessageAnnotations.Add("messageKey", "messageValue"); message.Footer.Add("footerKey", "footerValue"); message.Header.DeliveryCount = 1; message.Header.Durable = true; message.Header.FirstAcquirer = true; message.Header.Priority = 1; message.Header.TimeToLive = TimeSpan.FromSeconds(60); DateTimeOffset time = DateTimeOffset.Now.AddDays(1); message.Properties.AbsoluteExpiryTime = time; message.Properties.ContentEncoding = "compress"; message.Properties.ContentType = "application/json"; message.Properties.CorrelationId = new AmqpMessageId("correlationId"); message.Properties.CreationTime = time; message.Properties.GroupId = "groupId"; message.Properties.GroupSequence = 5; message.Properties.MessageId = new AmqpMessageId("messageId"); message.Properties.ReplyTo = new AmqpAddress("replyTo"); message.Properties.ReplyToGroupId = "replyToGroupId"; message.Properties.Subject = "subject"; message.Properties.To = new AmqpAddress("to"); message.Properties.UserId = Encoding.UTF8.GetBytes("userId"); Assert.AreEqual(AmqpMessageBodyType.Data, message.Body.BodyType); Assert.IsTrue(message.Body.TryGetData(out IEnumerable <ReadOnlyMemory <byte> > body)); Assert.AreEqual("some data", Encoding.UTF8.GetString(body.First().ToArray())); Assert.AreEqual("applicationValue", message.ApplicationProperties["applicationKey"]); Assert.AreEqual("deliveryValue", message.DeliveryAnnotations["deliveryKey"]); Assert.AreEqual("messageValue", message.MessageAnnotations["messageKey"]); Assert.AreEqual("footerValue", message.Footer["footerKey"]); Assert.AreEqual(1, message.Header.DeliveryCount); Assert.IsTrue(message.Header.Durable); Assert.IsTrue(message.Header.FirstAcquirer); Assert.AreEqual(1, message.Header.Priority); Assert.AreEqual(TimeSpan.FromSeconds(60), message.Header.TimeToLive); Assert.AreEqual(time, message.Properties.AbsoluteExpiryTime); Assert.AreEqual("compress", message.Properties.ContentEncoding); Assert.AreEqual("application/json", message.Properties.ContentType); Assert.AreEqual("correlationId", message.Properties.CorrelationId.ToString()); Assert.AreEqual(time, message.Properties.CreationTime); Assert.AreEqual("groupId", message.Properties.GroupId); Assert.AreEqual(5, message.Properties.GroupSequence); Assert.AreEqual("messageId", message.Properties.MessageId.ToString()); Assert.AreEqual("replyTo", message.Properties.ReplyTo.ToString()); Assert.AreEqual("replyToGroupId", message.Properties.ReplyToGroupId); Assert.AreEqual("subject", message.Properties.Subject); Assert.AreEqual("to", message.Properties.To.ToString()); Assert.AreEqual("userId", Encoding.UTF8.GetString(message.Properties.UserId.Value.ToArray())); }
/// <summary> /// Retrieves the partition key of an event from an <see cref="AmqpAnnotatedMessage" />. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="defaultValue">The value to return if the partition key is not represented in the <paramref name="instance"/>.</param> /// /// <returns>The partition key, if represented in the <paramref name="instance"/>; otherwise, <paramref name="defaultValue"/>.</returns> /// public static string GetPartitionKey(this AmqpAnnotatedMessage instance, string defaultValue = default) { if ((instance.HasSection(AmqpMessageSection.MessageAnnotations)) && (instance.MessageAnnotations.TryGetValue(AmqpProperty.PartitionKey.ToString(), out var value))) { return((string)value); } return(defaultValue); }
/// <summary> /// Retrieves the time that an event was enqueued in the partition from an <see cref="AmqpAnnotatedMessage" />. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="defaultValue">The value to return if the enqueue time is not represented in the <paramref name="instance"/>.</param> /// /// <returns>The enqueued time, if represented in the <paramref name="instance"/>; otherwise, <paramref name="defaultValue"/>.</returns> /// public static DateTimeOffset GetEnqueuedTime(this AmqpAnnotatedMessage instance, DateTimeOffset defaultValue = default) { if ((instance.HasSection(AmqpMessageSection.MessageAnnotations)) && (instance.MessageAnnotations.TryGetValue(AmqpProperty.EnqueuedTime.ToString(), out var value))) { return((DateTimeOffset)value); } return(defaultValue); }
/// <summary> /// Retrieves the time that the information about the last event enqueued in the partition was reported from an <see cref="AmqpAnnotatedMessage" />. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="defaultValue">The value to return if the last retrieval time is not represented in the <paramref name="instance"/>.</param> /// /// <returns>The time that the information about the last event enqueued in the partition was reported, if represented in the <paramref name="instance"/>; otherwise, <paramref name="defaultValue"/>.</returns> /// public static DateTimeOffset?GetLastPartitionPropertiesRetrievalTime(this AmqpAnnotatedMessage instance, DateTimeOffset?defaultValue = default) { if ((instance.HasSection(AmqpMessageSection.DeliveryAnnotations)) && (instance.DeliveryAnnotations.TryGetValue(AmqpProperty.LastPartitionPropertiesRetrievalTimeUtc.ToString(), out var value))) { return((DateTimeOffset)value); } return(defaultValue); }
/// <summary> /// Retrieves the offset of the last event published to the partition from an <see cref="AmqpAnnotatedMessage" />. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="defaultValue">The value to return if the last offset is not represented in the <paramref name="instance"/>.</param> /// /// <returns>The offset of the last event published to the partition, if represented in the <paramref name="instance"/>; otherwise, <paramref name="defaultValue"/>.</returns> /// public static long?GetLastPartitionOffset(this AmqpAnnotatedMessage instance, long?defaultValue = default) { if ((instance.HasSection(AmqpMessageSection.DeliveryAnnotations)) && (instance.DeliveryAnnotations.TryGetValue(AmqpProperty.PartitionLastEnqueuedOffset.ToString(), out var value))) { return((long)value); } return(defaultValue); }
public void CopyConstructorCopies() { var message = new AmqpAnnotatedMessage( new BinaryData[] { BinaryData.FromString("some data") }); message.ApplicationProperties.Add("applicationKey", "applicationValue"); message.DeliveryAnnotations.Add("deliveryKey", "deliveryValue"); message.MessageAnnotations.Add("messageKey", "messageValue"); message.Footer.Add("footerKey", "footerValue"); message.Header.DeliveryCount = 1; message.Header.Durable = true; message.Header.FirstAcquirer = true; message.Header.Priority = 1; message.Header.TimeToLive = TimeSpan.FromSeconds(60); message.Properties.AbsoluteExpiryTime = DateTimeOffset.Now.AddDays(1); message.Properties.ContentEncoding = "compress"; message.Properties.ContentType = "application/json"; message.Properties.CorrelationId = "correlationId"; message.Properties.CreationTime = DateTimeOffset.Now; message.Properties.GroupId = "groupId"; message.Properties.GroupSequence = 5; message.Properties.MessageId = "messageId"; message.Properties.ReplyTo = "replyTo"; message.Properties.ReplyToGroupId = "replyToGroupId"; message.Properties.Subject = "subject"; message.Properties.To = "to"; message.Properties.UserId = BinaryData.FromString("userId"); var copy = new AmqpAnnotatedMessage(message); Assert.AreEqual(((AmqpDataMessageBody)message.Body).Data.ToArray(), ((AmqpDataMessageBody)copy.Body).Data.ToArray()); Assert.AreEqual(message.ApplicationProperties["applicationKey"], copy.ApplicationProperties["applicationKey"]); Assert.AreEqual(message.DeliveryAnnotations["deliveryKey"], copy.DeliveryAnnotations["deliveryKey"]); Assert.AreEqual(message.MessageAnnotations["messageKey"], copy.MessageAnnotations["messageKey"]); Assert.AreEqual(message.Footer["footerKey"], copy.Footer["footerKey"]); Assert.AreEqual(message.Header.DeliveryCount, copy.Header.DeliveryCount); Assert.AreEqual(message.Header.Durable, copy.Header.Durable); Assert.AreEqual(message.Header.FirstAcquirer, copy.Header.FirstAcquirer); Assert.AreEqual(message.Header.Priority, copy.Header.Priority); Assert.AreEqual(message.Header.TimeToLive, copy.Header.TimeToLive); Assert.AreEqual(message.Properties.AbsoluteExpiryTime, copy.Properties.AbsoluteExpiryTime); Assert.AreEqual(message.Properties.ContentEncoding, copy.Properties.ContentEncoding); Assert.AreEqual(message.Properties.ContentType, copy.Properties.ContentType); Assert.AreEqual(message.Properties.CorrelationId, copy.Properties.CorrelationId); Assert.AreEqual(message.Properties.AbsoluteExpiryTime, copy.Properties.AbsoluteExpiryTime); Assert.AreEqual(message.Properties.CreationTime, copy.Properties.CreationTime); Assert.AreEqual(message.Properties.GroupId, copy.Properties.GroupId); Assert.AreEqual(message.Properties.GroupSequence, copy.Properties.GroupSequence); Assert.AreEqual(message.Properties.MessageId, copy.Properties.MessageId); Assert.AreEqual(message.Properties.ReplyTo, copy.Properties.ReplyTo); Assert.AreEqual(message.Properties.ReplyToGroupId, copy.Properties.ReplyToGroupId); Assert.AreEqual(message.Properties.Subject, copy.Properties.Subject); Assert.AreEqual(message.Properties.To, copy.Properties.To); Assert.AreEqual(message.Properties.UserId, copy.Properties.UserId); }
/// <summary> /// Retrieves the offset of an event from an <see cref="AmqpAnnotatedMessage" />. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="defaultValue">The value to return if the offset is not represented in the <paramref name="instance"/>.</param> /// /// <returns>The offset, if represented in the <paramref name="instance"/>; otherwise, <paramref name="defaultValue"/>.</returns> /// public static long GetOffset(this AmqpAnnotatedMessage instance, long defaultValue = long.MinValue) { if ((instance.HasSection(AmqpMessageSection.MessageAnnotations)) && (instance.MessageAnnotations.TryGetValue(AmqpProperty.Offset.ToString(), out var value))) { return((long)value); } return(defaultValue); }
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."); }
private static ServiceBusReceivedMessage CreateServiceBusReceivedMessage(AmqpAnnotatedMessage amqpMessage) { var serviceBusMessage = (ServiceBusReceivedMessage)Activator.CreateInstance( type: typeof(ServiceBusReceivedMessage), bindingAttr: BindingFlags.NonPublic | BindingFlags.Instance, binder: null, args: new object[] { amqpMessage }, culture: null, activationAttributes: null); return(serviceBusMessage); }
/// <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)); AmqpMessage = new AmqpAnnotatedMessage(receivedMessage.AmqpMessage); AmqpMessage.Header.DeliveryCount = null; AmqpMessage.MessageAnnotations.Remove(AmqpMessageConstants.LockedUntilName); AmqpMessage.MessageAnnotations.Remove(AmqpMessageConstants.SequenceNumberName); AmqpMessage.MessageAnnotations.Remove(AmqpMessageConstants.DeadLetterSourceName); AmqpMessage.MessageAnnotations.Remove(AmqpMessageConstants.EnqueueSequenceNumberName); AmqpMessage.MessageAnnotations.Remove(AmqpMessageConstants.EnqueuedTimeUtcName); ApplicationProperties.Remove(AmqpMessageConstants.DeadLetterReasonHeader); ApplicationProperties.Remove(AmqpMessageConstants.DeadLetterErrorDescriptionHeader); }
private static AmqpAnnotatedMessage CreateAmqpMessage() { var order = new Order(); string json = JsonConvert.SerializeObject(order); byte[] bytes = Encoding.UTF8.GetBytes(json); var message = new AmqpAnnotatedMessage(new AmqpMessageBody(new[] { new ReadOnlyMemory <byte>(bytes) })); message.Header.DeliveryCount = BogusGenerator.Random.UInt(); return(message); }
/// <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 GetEventBodyDoesNotAllowNonDataBodyTypes(AmqpMessageBodyType bodyType) { var body = bodyType switch { AmqpMessageBodyType.Sequence => AmqpMessageBody.FromSequence(new[] { new List <object> { 1, 2, 3 } }), AmqpMessageBodyType.Value => AmqpMessageBody.FromValue("This is a value"), _ => throw new ArgumentException($"Unsupported body type { bodyType }", nameof(bodyType)) }; var message = new AmqpAnnotatedMessage(body); Assert.That(() => message.GetEventBody(), Throws.InstanceOf <NotSupportedException>()); }
public void CreateProperties_FromMessage_AssignsEnqueuedTimeCorrectly() { // Arrange DateTime expected = BogusGenerator.Date.Recent(); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.MessageAnnotations["x-opt-enqueued-time"] = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal(expected, systemProperties.EnqueuedTime); }
public void CreateProperties_FromMessage_AssignsLockedUntilCorrectly() { // Arrange DateTime expected = BogusGenerator.Date.Past(); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.MessageAnnotations["x-opt-locked-until"] = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal(expected, systemProperties.LockedUntil); }
public void CreateProperties_FromMessage_AssignsDeadLetterSourceCorrectly() { // Arrange string expected = BogusGenerator.Random.String(); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.MessageAnnotations["x-opt-deadletter-source"] = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal(expected, systemProperties.DeadLetterSource); }
public void CreateProperties_FromMessage_AssignsContentTypeCorrectly() { // Arrange string expected = BogusGenerator.Random.String(); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.Properties.ContentType = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal(expected, systemProperties.ContentType); }
public void CreateProperties_FromMessage_AssignsDeliveryCountCorrectly() { // Arrange uint expected = BogusGenerator.Random.UInt(); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.Header.DeliveryCount = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal((int)expected, systemProperties.DeliveryCount); }
public void CreateProperties_FromMessage_AssignsIsReceivedCorrectly() { // Arrange long expected = BogusGenerator.Random.Long(min: 0); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); amqpMessage.MessageAnnotations["x-opt-enqueue-sequence-number"] = expected; ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.True(systemProperties.IsReceived); }
public void CreateProperties_FromMessage_AssignsLockTokenCorrectly(string lockToken) { // Arrange Guid.TryParse(lockToken, out Guid expected); AmqpAnnotatedMessage amqpMessage = CreateAmqpMessage(); ServiceBusReceivedMessage message = CreateServiceBusReceivedMessage(amqpMessage); SetLockToken(message, expected); // Act var systemProperties = AzureServiceBusSystemProperties.CreateFrom(message); // Assert Assert.Equal(expected, Guid.Parse(systemProperties.LockToken)); Assert.Equal(expected != null, systemProperties.IsLockTokenSet); }
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( new AmqpMessageBody( 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 copy of the <paramref name="instance"/>, cloning its attributes into a new instance. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// /// <returns>A copy of <see cref="AmqpAnnotatedMessage" /> containing the same data.</returns> /// public static AmqpAnnotatedMessage Clone(this AmqpAnnotatedMessage instance) { if (instance == null) { return(null); } var clone = new AmqpAnnotatedMessage(CloneBody(instance.Body)); if (instance.HasSection(AmqpMessageSection.Header)) { CopyHeaderSection(instance.Header, clone.Header); } if (instance.HasSection(AmqpMessageSection.Properties)) { CopyPropertiesSection(instance.Properties, clone.Properties); } if (instance.HasSection(AmqpMessageSection.Footer)) { CopyDictionary(instance.Footer, clone.Footer); } if (instance.HasSection(AmqpMessageSection.DeliveryAnnotations)) { CopyDictionary(instance.DeliveryAnnotations, clone.DeliveryAnnotations); } if (instance.HasSection(AmqpMessageSection.MessageAnnotations)) { CopyDictionary(instance.MessageAnnotations, clone.MessageAnnotations); } if (instance.HasSection(AmqpMessageSection.ApplicationProperties)) { CopyDictionary(instance.ApplicationProperties, clone.ApplicationProperties); } return(clone); }
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 amqp = new AmqpAnnotatedMessage( new BinaryData[] { new BinaryData(GetRandomBuffer(100)), new BinaryData(GetRandomBuffer(100)) }); var msg = new ServiceBusMessage() { AmqpMessage = amqp }; await sender.SendMessageAsync(msg); var receiver = client.CreateReceiver(scope.QueueName); var received = await receiver.ReceiveMessageAsync(); var bodyEnum = ((AmqpDataBody)received.AmqpMessage.Body).Data.GetEnumerator(); int ct = 0; foreach (BinaryData data in ((AmqpDataBody)msg.AmqpMessage.Body).Data) { bodyEnum.MoveNext(); var bytes = data.ToBytes().ToArray(); Assert.AreEqual(bytes, bodyEnum.Current.ToBytes().ToArray()); if (ct++ == 0) { Assert.AreEqual(bytes, received.Body.ToBytes().Slice(0, 100).ToArray()); } else { Assert.AreEqual(bytes, received.Body.ToBytes().Slice(100, 100).ToArray()); } } } }
/// <summary> /// Creates an <see cref="ServiceBusReceivedMessage"/> based on the given <paramref name="messageBody"/>. /// </summary> /// <param name="messageBody">The custom typed message body to wrap inside an Azure Service Bus message.</param> /// <param name="applicationPropertyKey">The additional application property key to add to the message.</param> /// <param name="applicationPropertyValue">The additional application property value to add to the message.</param> /// <param name="operationId">The optional correlation operation ID to add to the message.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="messageBody"/> is <c>null</c>.</exception> public static ServiceBusReceivedMessage AsServiceBusReceivedMessage( this object messageBody, string applicationPropertyKey = null, object applicationPropertyValue = null, string operationId = null) { Guard.NotNull(messageBody, nameof(messageBody), "Requires a message body to wrap in an received Azure Service Bus message"); string serializedMessageBody = JsonConvert.SerializeObject(messageBody); byte[] rawMessage = Encoding.UTF8.GetBytes(serializedMessageBody); var amqp = new AmqpAnnotatedMessage(new AmqpMessageBody(new[] { new ReadOnlyMemory <byte>(rawMessage) })); amqp.Header.DeliveryCount = BogusGenerator.Random.UInt(); if (operationId is null) { amqp.Properties.CorrelationId = new AmqpMessageId(); } else { amqp.Properties.CorrelationId = new AmqpMessageId(operationId); } if (applicationPropertyKey != null) { amqp.ApplicationProperties[applicationPropertyKey] = applicationPropertyValue; } var serviceBusMessage = (ServiceBusReceivedMessage)Activator.CreateInstance( type: typeof(ServiceBusReceivedMessage), bindingAttr: BindingFlags.NonPublic | BindingFlags.Instance, binder: null, args: new object[] { amqp }, culture: null, activationAttributes: null); return(serviceBusMessage); }