Exemple #1
0
        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.");
        }
Exemple #2
0
        public void CloneDoesNotForceAllocationOfUnpopulatedSections()
        {
            var firstBody = new List <object> {
                1, 2, 3
            };
            var secondBody = new List <object> {
                4, 5, 6
            };
            var body   = AmqpMessageBody.FromSequence(new[] { firstBody, secondBody });
            var source = new AmqpAnnotatedMessage(body);
            var clone  = source.Clone();

            // Body

            Assert.That(ReferenceEquals(clone.Body, source.Body), Is.False, "The message body should not be the same instance.");
            Assert.That(source.Body.TryGetSequence(out var sourceBody), Is.True, "The source should have a sequence body.");
            Assert.That(clone.Body.TryGetSequence(out var cloneBody), Is.True, "The clone should have a sequence body.");
            Assert.That(cloneBody, Is.EquivalentTo(sourceBody), "The body data should match.");

            // Other sections

            Assert.That(clone.HasSection(AmqpMessageSection.Body), Is.True, "The body should be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.Header), Is.False, "The header should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.Properties), Is.False, "The properties should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.Footer), Is.False, "The footer should be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.DeliveryAnnotations), Is.False, "The delivery annotations should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.MessageAnnotations), Is.False, "The message annotations should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.ApplicationProperties), Is.False, "The application properties should not be populated.");
        }
Exemple #3
0
        public void CloneAllocatesWhenSectionsArePopulated()
        {
            var body   = AmqpMessageBody.FromValue("this is an awesome value!");
            var source = new AmqpAnnotatedMessage(body);

            source.Footer.Add("footOne", "1111");
            source.ApplicationProperties.Add("appProp", "1111");

            var clone = source.Clone();

            // Body

            Assert.That(ReferenceEquals(clone.Body, source.Body), Is.False, "The message body should not be the same instance.");
            Assert.That(source.Body.TryGetValue(out var sourceBody), Is.True, "The source should have a value body.");
            Assert.That(clone.Body.TryGetValue(out var cloneBody), Is.True, "The clone should have a value body.");
            Assert.That(cloneBody, Is.EqualTo(sourceBody), "The body data should match.");

            // Other sections

            Assert.That(clone.HasSection(AmqpMessageSection.Body), Is.True, "The body should be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.Footer), Is.True, "The footer should be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.ApplicationProperties), Is.True, "The application properties should be populated.");

            Assert.That(clone.HasSection(AmqpMessageSection.Header), Is.False, "The header should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.Properties), Is.False, "The properties should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.DeliveryAnnotations), Is.False, "The delivery annotations should not be populated.");
            Assert.That(clone.HasSection(AmqpMessageSection.MessageAnnotations), Is.False, "The message annotations should not be populated.");
        }
        public void ManagesMultipleAmqpDataSegmentsByCopyingEagerly()
        {
            byte[] firstSegment  = new byte[] { 1, 2, 3 };
            byte[] secondSegment = new byte[] { 4, 5, 6 };

            var message = new AmqpMessageBody(MessageBody.FromDataSegments(new[]
            {
                new Data {
                    Value = new ArraySegment <byte>(firstSegment)
                }, new Data {
                    Value = new ArraySegment <byte>(secondSegment)
                }
            }));

            message.TryGetData(out var body);
            var firstSegmentBeforeConversion  = body.ElementAt(0);
            var secondSegmentBeforeConversion = body.ElementAt(1);

            ReadOnlyMemory <byte> fromReadOnlyMemorySegments = MessageBody.FromReadOnlyMemorySegments(body);
            ReadOnlyMemory <byte> convertedASecondTime       = MessageBody.FromReadOnlyMemorySegments(body);

            var firstSegmentAfterConversion  = body.ElementAt(0);
            var secondSegmentAfterConversion = body.ElementAt(1);

            Assert.IsFalse(firstSegment.Equals(firstSegmentBeforeConversion));
            Assert.IsFalse(secondSegment.Equals(secondSegmentBeforeConversion));

            Assert.IsFalse(firstSegment.Equals(firstSegmentAfterConversion));
            Assert.IsFalse(secondSegment.Equals(secondSegmentAfterConversion));

            Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6 }, fromReadOnlyMemorySegments.ToArray());
            Assert.IsTrue(fromReadOnlyMemorySegments.Equals(convertedASecondTime));
        }
Exemple #5
0
        public async Task CanRoundTripAbsoluteExpiryCreationTime()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var message     = new ServiceBusMessage();
                var amqpMessage = message.GetRawAmqpMessage();

                // body
                amqpMessage.Body = AmqpMessageBody.FromValue("body");

                // properties
                var expiry   = DateTimeOffset.Now.AddDays(1);
                var creation = DateTimeOffset.Now.AddMinutes(1);
                amqpMessage.Properties.AbsoluteExpiryTime = expiry;
                amqpMessage.Properties.CreationTime       = creation;

                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                var sender = client.CreateSender(scope.QueueName);

                var now = DateTimeOffset.UtcNow;
                await sender.SendMessageAsync(message);

                var receiver = client.CreateReceiver(scope.QueueName);
                var received = (await receiver.ReceiveMessageAsync()).GetRawAmqpMessage();

                received.Body.TryGetValue(out var body);
                Assert.AreEqual("body", body);

                Assert.AreEqual(expiry.ToUnixTimeSeconds(), received.Properties.AbsoluteExpiryTime.Value.ToUnixTimeSeconds());
                Assert.AreEqual(creation.ToUnixTimeSeconds(), received.Properties.CreationTime.Value.ToUnixTimeSeconds());
            }
        }
Exemple #6
0
        public async Task CanSendValueSection(object value)
        {
            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();
                msg.GetRawAmqpMessage().Body = AmqpMessageBody.FromValue(value);

                await sender.SendMessageAsync(msg);

                var receiver = client.CreateReceiver(scope.QueueName);
                var received = await receiver.ReceiveMessageAsync();

                received.GetRawAmqpMessage().Body.TryGetValue(out var receivedData);
                Assert.AreEqual(value, receivedData);

                Assert.That(
                    () => received.Body,
                    Throws.InstanceOf <NotSupportedException>());

                var sendable = new ServiceBusMessage(received);
                sendable.GetRawAmqpMessage().Body.TryGetValue(out var sendData);
                Assert.AreEqual(value, sendData);
            }
        }
        public void ManagesMultipleReadOnlyMemoriesByCopyingOnConversion()
        {
            ReadOnlyMemory <byte> firstSegment  = new byte[] { 1, 2, 3 };
            ReadOnlyMemory <byte> secondSegment = new byte[] { 4, 5, 6 };

            var message = new AmqpMessageBody(MessageBody.FromReadOnlyMemorySegments(new[] { firstSegment, secondSegment }));

            message.TryGetData(out var body);
            var firstSegmentBeforeConversion  = body.ElementAt(0);
            var secondSegmentBeforeConversion = body.ElementAt(1);

            ReadOnlyMemory <byte> fromReadOnlyMemorySegments = MessageBody.FromReadOnlyMemorySegments(body);
            ReadOnlyMemory <byte> convertedASecondTime       = MessageBody.FromReadOnlyMemorySegments(body);

            var firstSegmentAfterConversion  = body.ElementAt(0);
            var secondSegmentAfterConversion = body.ElementAt(1);

            Assert.IsTrue(firstSegment.Equals(firstSegmentBeforeConversion));
            Assert.IsTrue(secondSegment.Equals(secondSegmentBeforeConversion));

            Assert.IsFalse(firstSegment.Equals(firstSegmentAfterConversion));
            Assert.IsFalse(secondSegment.Equals(secondSegmentAfterConversion));

            Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6 }, fromReadOnlyMemorySegments.ToArray());
            Assert.IsTrue(fromReadOnlyMemorySegments.Equals(convertedASecondTime));
        }
Exemple #8
0
        /// <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);
        }
Exemple #9
0
        public void ManagesMultipleAmqpDataSegmentsByCopyingEagerly()
        {
            var firstSegment     = new byte[] { 1, 2, 3 };
            var secondSegment    = new byte[] { 4, 5, 6 };
            var allSegmentsArray = new byte[] { 1, 2, 3, 4, 5, 6 };

            var message = new AmqpMessageBody(MessageBody.FromDataSegments(new[]
            {
                new Data {
                    Value = new ArraySegment <byte>(firstSegment)
                },
                new Data {
                    Value = new ArraySegment <byte>(secondSegment)
                }
            }));

            message.TryGetData(out var body);

            var firstSegmentBeforeConversion  = body.ElementAt(0);
            var secondSegmentBeforeConversion = body.ElementAt(1);
            var fromReadOnlyMemorySegments    = (ReadOnlyMemory <byte>)MessageBody.FromReadOnlyMemorySegments(body);
            var convertedASecondTime          = (ReadOnlyMemory <byte>)MessageBody.FromReadOnlyMemorySegments(body);
            var firstSegmentAfterConversion   = body.ElementAt(0);
            var secondSegmentAfterConversion  = body.ElementAt(1);

            Assert.That(firstSegmentBeforeConversion, Is.Not.EqualTo(firstSegment), "The first segment should not match before conversion.");
            Assert.That(secondSegmentBeforeConversion, Is.Not.EqualTo(secondSegment), "The second segment should not match before conversion.");
            Assert.That(firstSegmentAfterConversion, Is.Not.EqualTo(firstSegment), "The first segment should not match after conversion.");
            Assert.That(secondSegmentAfterConversion, Is.Not.EqualTo(secondSegment), "The second segment should not match after conversion.");
            Assert.That(fromReadOnlyMemorySegments.ToArray(), Is.EquivalentTo(allSegmentsArray), "The unified segments should match.");
            Assert.That(convertedASecondTime, Is.EqualTo(fromReadOnlyMemorySegments), "The unified segments should match when converted a second time.");
        }
Exemple #10
0
        public async Task CanSendSequenceSection(IEnumerable <IList <object> > sequence)
        {
            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();
                msg.GetRawAmqpMessage().Body = AmqpMessageBody.FromSequence(sequence);

                await sender.SendMessageAsync(msg);

                var receiver = client.CreateReceiver(scope.QueueName);
                var received = await receiver.ReceiveMessageAsync();

                received.GetRawAmqpMessage().Body.TryGetSequence(out IEnumerable <IList <object> > receivedData);
                var outerEnum = receivedData.GetEnumerator();
                foreach (IList <object> seq in sequence)
                {
                    outerEnum.MoveNext();
                    var innerEnum = outerEnum.Current.GetEnumerator();
                    foreach (object elem in seq)
                    {
                        innerEnum.MoveNext();
                        Assert.AreEqual(elem, innerEnum.Current);
                    }
                }

                Assert.That(
                    () => received.Body,
                    Throws.InstanceOf <NotSupportedException>());
            }
        }
        public void CanCreateDataBody()
        {
            var body = new AmqpMessageBody(Array.Empty <ReadOnlyMemory <byte> >());

            Assert.AreEqual(AmqpMessageBodyType.Data, body.BodyType);
            Assert.IsTrue(body.TryGetData(out var data));
            Assert.NotNull(data);
        }
Exemple #12
0
        /// <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);
        }
Exemple #13
0
        public void CannotUseCustomType()
        {
            Assert.That(
                () => AmqpMessageBody.FromValue(new Test()),
                Throws.InstanceOf <NotSupportedException>());

            Assert.That(
                () => AmqpMessageBody.FromSequence(Enumerable.Repeat(new Test[] { new Test() }, 1)),
                Throws.InstanceOf <NotSupportedException>());
        }
        public void BodyIsDetectedByHasSection()
        {
            var message = new AmqpAnnotatedMessage(EmptyDataBody);

            message.Body = null;
            Assert.False(message.HasSection(AmqpMessageSection.Body));

            message.Body = AmqpMessageBody.FromValue("this is a string value");
            Assert.True(message.HasSection(AmqpMessageSection.Body));
        }
Exemple #15
0
        public void ManagesSingleReadOnlyMemoryWithoutCopying()
        {
            var singleReadOnlyMemory = new ReadOnlyMemory <byte>(new byte[] { 1, 2, 3 });
            var message = new AmqpMessageBody(MessageBody.FromReadOnlyMemorySegment(singleReadOnlyMemory));

            message.TryGetData(out var body);
            var fromReadOnlyMemorySegments = (ReadOnlyMemory <byte>)MessageBody.FromReadOnlyMemorySegments(body);

            Assert.That(fromReadOnlyMemorySegments, Is.EqualTo(singleReadOnlyMemory));
        }
        public void ManagesSingleReadOnlyMemoryWithoutCopying()
        {
            ReadOnlyMemory <byte> singleReadOnlyMemory = new byte[] { 1, 2, 3 };

            var message = new AmqpMessageBody(MessageBody.FromReadOnlyMemorySegment(singleReadOnlyMemory));

            message.TryGetData(out var body);
            ReadOnlyMemory <byte> fromReadOnlyMemorySegments = MessageBody.FromReadOnlyMemorySegments(body);

            Assert.IsTrue(singleReadOnlyMemory.Equals(fromReadOnlyMemorySegments));
        }
        public void Convert_ValueBodyMessage_String()
        {
            ServiceBusReceivedMessage message = ServiceBusModelFactory.ServiceBusReceivedMessage();

            message.GetRawAmqpMessage().Body = AmqpMessageBody.FromValue("value");

            MessageToStringConverter converter = new MessageToStringConverter();
            string result = converter.Convert(message);

            Assert.AreEqual("value", result);
        }
        public void Convert_SequenceBodyMessage_Throws()
        {
            ServiceBusReceivedMessage message = ServiceBusModelFactory.ServiceBusReceivedMessage();

            message.GetRawAmqpMessage().Body = AmqpMessageBody.FromSequence(new IList <object>[] { new object[] { "sequence" } });

            MessageToStringConverter converter = new MessageToStringConverter();

            Assert.That(
                () => converter.Convert(message),
                Throws.InstanceOf <NotSupportedException>());
        }
        public void Convert_ValueBodyMessage_NonStringThrows()
        {
            ServiceBusReceivedMessage message = ServiceBusModelFactory.ServiceBusReceivedMessage();

            message.GetRawAmqpMessage().Body = AmqpMessageBody.FromValue(5);

            MessageToStringConverter converter = new MessageToStringConverter();

            Assert.That(
                () => converter.Convert(message),
                Throws.InstanceOf <NotSupportedException>());
        }
Exemple #20
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.");
        }
        public void CanCreateValueBody()
        {
            var body = new AmqpMessageBody("value");

            Assert.AreEqual(AmqpMessageBodyType.Value, body.BodyType);
            Assert.IsTrue(body.TryGetValue(out var value));
            Assert.AreEqual("value", value);

            Assert.IsFalse(body.TryGetData(out var data));
            Assert.IsNull(data);

            Assert.IsFalse(body.TryGetSequence(out var sequence));
            Assert.IsNull(sequence);
        }
Exemple #22
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);
        }
Exemple #23
0
        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);
        }
Exemple #24
0
        public void CanCreateValueBody(object input)
        {
            var body = AmqpMessageBody.FromValue(input);

            Assert.AreEqual(AmqpMessageBodyType.Value, body.BodyType);
            Assert.IsTrue(body.TryGetValue(out var output));
            Assert.AreEqual(input, output);

            Assert.IsFalse(body.TryGetData(out var data));
            Assert.IsNull(data);

            Assert.IsFalse(body.TryGetSequence(out var sequence));
            Assert.IsNull(sequence);
        }
Exemple #25
0
        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>());
        }
Exemple #26
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.");
        }
Exemple #27
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>());
        }
Exemple #28
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.");
        }
Exemple #29
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;
        }
Exemple #30
0
        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());
                    }
                }
            }
        }