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()));
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #10
0
        /// <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);
        }
Beispiel #11
0
        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.");
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
 /// <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);
 }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        /// <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);
        }
Beispiel #16
0
        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.");
        }
Beispiel #17
0
        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>());
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        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.");
        }
Beispiel #26
0
        /// <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());
                    }
                }
            }
        }
Beispiel #28
0
        /// <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);
        }