internal TAs ReadObjectInternal <T, TAs>(Stream stream)
        {
            TAs tA;

            if (!stream.CanSeek)
            {
                throw new AmqpException(AmqpError.DecodeError, "stream.CanSeek must be true.");
            }
            SerializableType type             = this.GetType(typeof(T));
            ByteBuffer       byteBuffer       = null;
            long             position         = stream.Position;
            BufferListStream bufferListStream = stream as BufferListStream;

            if (bufferListStream == null)
            {
                byteBuffer = new ByteBuffer((int)stream.Length, false);
                int num = stream.Read(byteBuffer.Buffer, 0, byteBuffer.Capacity);
                byteBuffer.Append(num);
            }
            else
            {
                ArraySegment <byte> nums = bufferListStream.ReadBytes(2147483647);
                byteBuffer = new ByteBuffer(nums.Array, nums.Offset, nums.Count);
            }
            using (byteBuffer)
            {
                TAs tA1 = (TAs)type.ReadObject(byteBuffer);
                if (byteBuffer.Length > 0)
                {
                    stream.Position = position + (long)byteBuffer.Offset;
                }
                tA = tA1;
            }
            return(tA);
        }
示例#2
0
        public void should_be_able_to_read_a_string_from_multiple_segments()
        {
            string   expected = "The quick brown fox jumps over the lazy dog";
            Encoding encoding = Encoding.ASCII;

            // create n-segments of each word and space
            Random random = new Random(0);

            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();
            var words = expected.Split(' ');

            for (int i = 0; i < words.Length; i++)
            {
                if (i != 0)
                {
                    segments.Add(GetSegment(encoding.GetBytes(" "), random.Next(0, 256), random.Next(1, 4) * 1024));
                }

                segments.Add(GetSegment(encoding.GetBytes(words[i]), random.Next(0, 256), random.Next(1, 4) * 1024));
            }

            BufferListStream sut = new BufferListStream();

            sut.Initialize(segments);

            // pre-condition
            Assert.AreEqual(expected.Length, sut.Length);

            string actual = sut.ReadString(expected.Length, encoding);

            Assert.AreEqual(expected, actual);
            Assert.AreEqual(expected.Length, sut.Position);
        }
        protected override async Task <Stream> OnGetStateAsync()
        {
            try
            {
                AmqpRequestMessage amqpRequestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.GetSessionStateOperation, this.OperationTimeout, null);
                amqpRequestMessage.Map[ManagementConstants.Properties.SessionId] = this.SessionId;

                AmqpResponseMessage amqpResponseMessage = await this.InnerMessageReceiver.ExecuteRequestResponseAsync(amqpRequestMessage).ConfigureAwait(false);

                Stream sessionState = null;
                if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                {
                    if (amqpResponseMessage.Map[ManagementConstants.Properties.SessionState] != null)
                    {
                        sessionState = new BufferListStream(new[] { amqpResponseMessage.GetValue <ArraySegment <byte> >(ManagementConstants.Properties.SessionState) });
                    }
                }

                return(sessionState);
            }
            catch (AmqpException amqpException)
            {
                throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error);
            }
        }
示例#4
0
        public void should_be_able_to_take_a_buffer_from_the_current_position()
        {
            BufferListStream            sut      = new BufferListStream();
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            for (int i = 0; i < 10; i++)
            {
                segments.Add(GetSegment(new byte[16], 512, 1024));
            }
            sut.Initialize(segments);

            // pre-condition
            Assert.AreEqual(0, sut.Position);

            sut.Position += 24;

            // act
            var actual = sut.Take(36);

            var totalLength = actual.Sum(segment => segment.Count);

            // assert
            Assert.IsNotNull(actual);
            Assert.AreEqual(36, totalLength);
            // TODO: check if the data is correct
        }
        protected override async Task OnSetStateAsync(Stream sessionState)
        {
            try
            {
                if (sessionState != null && sessionState.CanSeek && sessionState.Position != 0)
                {
                    throw new InvalidOperationException("CannotSerializeSessionStateWithPartiallyConsumedStream");
                }

                AmqpRequestMessage amqpRequestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.SetSessionStateOperation, this.OperationTimeout, null);
                amqpRequestMessage.Map[ManagementConstants.Properties.SessionId] = this.SessionId;

                if (sessionState != null)
                {
                    BufferListStream    buffer = BufferListStream.Create(sessionState, AmqpConstants.SegmentSize);
                    ArraySegment <byte> value  = buffer.ReadBytes((int)buffer.Length);
                    amqpRequestMessage.Map[ManagementConstants.Properties.SessionState] = value;
                }
                else
                {
                    amqpRequestMessage.Map[ManagementConstants.Properties.SessionState] = null;
                }

                await this.InnerMessageReceiver.ExecuteRequestResponseAsync(amqpRequestMessage).ConfigureAwait(false);
            }
            catch (AmqpException amqpException)
            {
                throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error);
            }
        }
示例#6
0
        internal TAs ReadObjectInternal <T, TAs>(Stream stream)
        {
            if (!stream.CanSeek)
            {
                throw new AmqpException(AmqpErrorCode.DecodeError, "stream.CanSeek must be true.");
            }

            SerializableType type       = this.GetType(typeof(T));
            ByteBuffer       buffer     = null;
            long             position   = stream.Position;
            BufferListStream listStream = stream as BufferListStream;

            if (listStream != null)
            {
                ArraySegment <byte> segment = listStream.ReadBytes(int.MaxValue);
                buffer = new ByteBuffer(segment.Array, segment.Offset, segment.Count);
            }
            else
            {
                buffer = new ByteBuffer((int)stream.Length, false);
                int bytes = stream.Read(buffer.Buffer, 0, buffer.Capacity);
                buffer.Append(bytes);
            }

            using (buffer)
            {
                TAs value = (TAs)type.ReadObject(buffer);
                if (buffer.Length > 0)
                {
                    stream.Position = position + buffer.Offset;
                }

                return(value);
            }
        }
示例#7
0
        public void should_not_be_able_to_skip_backwards()
        {
            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { GetSegment(new byte[] { 0x01, 0x02, 0x03, 0x04 }, 123, 1024) });
            sut.Position = 1;
            sut.Skip(-1);
        }
示例#8
0
 public ArraySegment <byte> PatternMatch()
 {
     using var messageStream = amqpMessage.ToStream();
     return(messageStream switch
     {
         BufferListStream bufferListStream => bufferListStream.ReadBytes((int)stream.Length),
         _ => throw new InvalidOperationException()
     });
 public BrokerMessage(AmqpMessage message)
 {
     this.stream = (BufferListStream)message.ToStream();
     foreach (var buffer in message.RawByteBuffers)
     {
         buffer.Clone();
     }
     this.RawByteBuffers = message.RawByteBuffers;
 }
示例#10
0
        private static Data ToData(AmqpMessage message)
        {
            ArraySegment <byte>[] payload = message.GetPayload();
            var buffer = new BufferListStream(payload);
            ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length);

            return(new Data {
                Value = value
            });
        }
示例#11
0
        public void should_be_able_to_skip_to_the_end_of_all_the_buffers()
        {
            int segmentSize = 16;
            BufferListStream            sut      = new BufferListStream();
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            segments.Add(GetSegment(new byte[segmentSize], 512, 1024));
            segments.Add(GetSegment(new byte[segmentSize], 512, 1024));
            sut.Initialize(segments);

            sut.Skip(segmentSize * 2);
        }
示例#12
0
        protected override async Task <long> OnScheduleMessageAsync(BrokeredMessage brokeredMessage)
        {
            // TODO: Ensure System.Transactions.Transaction.Current is null. Transactions are not supported by 1.0.0 version of dotnet core.
            using (AmqpMessage amqpMessage = AmqpMessageConverter.ClientGetMessage(brokeredMessage))
            {
                var request = AmqpRequestMessage.CreateRequest(
                    ManagementConstants.Operations.ScheduleMessageOperation,
                    this.OperationTimeout,
                    null);

                ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                BufferListStream      buffer  = new BufferListStream(payload);
                ArraySegment <byte>   value   = buffer.ReadBytes((int)buffer.Length);

                var entry = new AmqpMap();
                {
                    entry[ManagementConstants.Properties.Message]   = value;
                    entry[ManagementConstants.Properties.MessageId] = brokeredMessage.MessageId;

                    if (!string.IsNullOrWhiteSpace(brokeredMessage.SessionId))
                    {
                        entry[ManagementConstants.Properties.SessionId] = brokeredMessage.SessionId;
                    }

                    if (!string.IsNullOrWhiteSpace(brokeredMessage.PartitionKey))
                    {
                        entry[ManagementConstants.Properties.PartitionKey] = brokeredMessage.PartitionKey;
                    }
                }

                request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                    entry
                };

                IEnumerable <long> sequenceNumbers = null;
                var response = await this.ExecuteRequestResponseAsync(request);

                if (response.StatusCode == AmqpResponseStatusCode.OK)
                {
                    sequenceNumbers = response.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                }
                else
                {
                    response.ToMessagingContractException();
                }

                return(sequenceNumbers?.FirstOrDefault() ?? 0);
            }
        }
示例#13
0
        public void should_be_able_to_advance_the_position_into_the_next_segment()
        {
            BufferListStream            sut      = new BufferListStream();
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            segments.Add(GetSegment(new byte[16], 512, 1024));
            segments.Add(GetSegment(new byte[16], 512, 1024));
            sut.Initialize(segments);

            Assert.AreEqual(0, sut.Position);

            sut.Position += 24;

            Assert.AreEqual(24, sut.Position);
        }
示例#14
0
        public void should_be_able_to_advance_the_position_within_current_segment()
        {
            int segmentLength    = 16;
            int expectedPosition = segmentLength / 2;

            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { GetSegment(new byte[segmentLength], 512, 1024) });

            Assert.AreEqual(0, sut.Position);

            sut.Position += expectedPosition;

            Assert.AreEqual(expectedPosition, sut.Position);
        }
        public static AmqpMessage BrokeredMessagesToAmqpMessage(IEnumerable <BrokeredMessage> brokeredMessages, bool batchable)
        {
            AmqpMessage amqpMessage;

            if (brokeredMessages.Count() == 1)
            {
                BrokeredMessage singleBrokeredMessage = brokeredMessages.Single();
                amqpMessage = AmqpMessageConverter.ClientGetMessage(singleBrokeredMessage);
            }
            else
            {
                List <Data> dataList = new List <Data>();
                foreach (BrokeredMessage brokeredMessage in brokeredMessages)
                {
                    AmqpMessage           amqpMessageItem = AmqpMessageConverter.ClientGetMessage(brokeredMessage);
                    ArraySegment <byte>[] payload         = amqpMessageItem.GetPayload();
                    BufferListStream      buffer          = new BufferListStream(payload);
                    ArraySegment <byte>   value           = buffer.ReadBytes((int)buffer.Length);
                    dataList.Add(new Data()
                    {
                        Value = value
                    });
                }

                BrokeredMessage firstBrokeredMessage = brokeredMessages.First();

                amqpMessage = AmqpMessage.Create(dataList);
                amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;

                if (firstBrokeredMessage.MessageId != null)
                {
                    amqpMessage.Properties.MessageId = firstBrokeredMessage.MessageId;
                }

                if (firstBrokeredMessage.SessionId != null)
                {
                    amqpMessage.Properties.GroupId = firstBrokeredMessage.SessionId;
                }

                if (firstBrokeredMessage.PartitionKey != null)
                {
                    amqpMessage.MessageAnnotations.Map[AmqpMessageConverter.PartitionKeyName] = firstBrokeredMessage.PartitionKey;
                }
            }

            amqpMessage.Batchable = batchable;
            return(amqpMessage);
        }
示例#16
0
        public void should_be_able_to_read_an_unsigned_integer(bool littleEndian, byte[] bytes, ulong expected)
        {
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            segments.Add(new ArraySegment <byte>(bytes));
            BufferListStream sut = new BufferListStream();

            sut.Initialize(segments);

            // act
            var actual = sut.ReadUInt32(littleEndian);

            // assert
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(4, sut.Position);
        }
示例#17
0
        public void should_be_able_to_call_skip_to_advance_the_position()
        {
            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { GetSegment(new byte[] { 0x01 }, 123, 1024) });

            // pre-condition
            Assert.AreEqual(1, sut.Length);

            // act
            var actual = sut.Skip(1);

            // assert
            Assert.NotNull(actual);
            Assert.AreEqual(1, sut.Position);
        }
示例#18
0
        public void should_be_able_to_read_a_string_from_segments()
        {
            string expected = "The quick brown fox jumps over the lazy dog";

            BufferListStream sut = new BufferListStream();

            sut.Initialize(GetSegments(expected, Encoding.ASCII, 2));

            // pre-condition
            Assert.AreEqual(expected.Length, sut.Length);

            var actual = sut.ReadString(expected.Length, Encoding.ASCII);

            // assert
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(expected.Length, sut.Position);
        }
示例#19
0
        public void should_be_able_to_read_a_long_integer(bool littleEndian, byte[] bytes, long expected)
        {
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            segments.Add(new ArraySegment <byte>(bytes));
            BufferListStream sut = new BufferListStream();

            sut.Initialize(segments);

            // act
            long actual = sut.ReadInt64(littleEndian);

            // assert
            Assert.AreEqual(8, bytes.Length);
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(8, sut.Position);
        }
示例#20
0
        public void should_be_able_to_read_a_byte_and_the_position_should_be_advanced_by_one()
        {
            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { GetSegment(new byte[] { 0x01, 0x02 }, 512, 1024) });

            // pre-condition
            Assert.AreEqual(2, sut.Length);
            Assert.AreEqual(0, sut.Position);

            // act
            var first = sut.ReadByte();

            // assert
            Assert.AreEqual(1, first);
            Assert.AreEqual(1, sut.Position);
        }
示例#21
0
        public void should_be_able_to_read_a_single_byte()
        {
            byte expected = 0x01;

            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { GetSegment(new byte[] { expected }, 123, 1024) });

            // pre-condition
            Assert.AreEqual(1, sut.Length);
            Assert.AreEqual(0, sut.Position);

            // act
            var actual = sut.ReadByte();

            // assert
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(1, sut.Position);
        }
示例#22
0
        public void should_be_able_to_read_a_string_from_one_segment()
        {
            string expected = "The quick brown fox jumps over the lazy dog";
            var    encoding = Encoding.ASCII;

            var bytes = encoding.GetBytes(expected);

            ArraySegment <byte> segment = new ArraySegment <byte>(bytes);

            BufferListStream sut = new BufferListStream();

            sut.Initialize(new[] { segment });

            // act
            var actual = sut.ReadString(expected.Length, encoding);

            // assert
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(expected.Length, sut.Position);
        }
示例#23
0
        public void should_be_able_to_rewind_the_position_into_the_previous_segment()
        {
            int segmentLength    = 16;
            int expectedPosition = segmentLength * 3 / 2;

            BufferListStream            sut      = new BufferListStream();
            List <ArraySegment <byte> > segments = new List <ArraySegment <byte> >();

            segments.Add(GetSegment(new byte[segmentLength], 512, 1024));
            segments.Add(GetSegment(new byte[segmentLength], 512, 1024));
            sut.Initialize(segments);

            Assert.AreEqual(0, sut.Position);

            sut.Position += expectedPosition;

            Assert.AreEqual(expectedPosition, sut.Position);

            sut.Position -= segmentLength;
            Assert.AreEqual(segmentLength / 2, sut.Position);
        }
示例#24
0
        public void AmqpMessageReceiveResendTest()
        {
            var message = AmqpMessage.Create(new AmqpValue {
                Value = "Hello, AMQP!"
            });

            message.MessageAnnotations.Map["key"] = "old";

            // send the message and receive it on remote side
            var payload       = message.GetPayload();
            var streamMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(payload));

            //new OutputMessage for resending with modified sections
            var stream = BufferListStream.Create(streamMessage.ToStream(), AmqpConstants.SegmentSize, streamMessage.Settled);

            stream.Seek(0, System.IO.SeekOrigin.Begin);
            var outMessage = AmqpMessage.CreateOutputMessage(stream, false);

            outMessage.Settled = streamMessage.Settled;
            //explicitly assign
            outMessage.Header.Priority = 99;
            outMessage.DeliveryAnnotations.Map["key"] = "da-update";
            outMessage.MessageAnnotations.Map["key"]  = "update";

            // send
            var payload2 = outMessage.GetPayload();
            var value    = (string)outMessage.MessageAnnotations.Map["key"];

            Assert.Equal("update", value);

            // receive
            var streamMessage2 = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(payload2));

            Assert.Equal(99, streamMessage2.Header.Priority.Value);
            value = (string)outMessage.DeliveryAnnotations.Map["key"];
            Assert.Equal("da-update", value);
            value = (string)outMessage.MessageAnnotations.Map["key"];
            Assert.Equal("update", value);
        }
示例#25
0
        public byte[] GetBytes()
        {
            this.ThrowIfDisposed();
            this.SetGetBodyCalled();
            if (this.bodyStream == null && this.receivedMessage == null)
            {
                return(new byte[0]);
            }
            if (this.receivedMessage != null)
            {
                this.bodyStream = this.receivedMessage.GetBody <Stream>();
            }
            BufferListStream bufferListStream  = this.bodyStream as BufferListStream;
            BufferListStream bufferListStream1 = bufferListStream;

            if (bufferListStream == null)
            {
                return(EventData.ReadFullStream(this.bodyStream));
            }
            byte[] numArray = new byte[checked ((IntPtr)bufferListStream1.Length)];
            bufferListStream1.Read(numArray, 0, (int)numArray.Length);
            return(numArray);
        }
示例#26
0
        public void should_be_able_to_get_correct_position()
        {
            var data     = Encoding.UTF8.GetBytes("SuperSocket rocks!");
            var segments = new List <ArraySegment <byte> >();

            segments.Add(new ArraySegment <byte>(data));

            using (var bufferListStream = new BufferListStream())
            {
                bufferListStream.Initialize(segments);

                Assert.AreEqual(data.Length, bufferListStream.Length);
                Assert.AreEqual(0, bufferListStream.Position);

                bufferListStream.Seek(1, SeekOrigin.Begin);
                Assert.AreEqual(1, bufferListStream.Position);

                bufferListStream.Seek(1, SeekOrigin.Current);
                Assert.AreEqual(2, bufferListStream.Position);

                bufferListStream.Seek(data.Length - 1, SeekOrigin.Begin);
                Assert.AreEqual(data.Length - 1, bufferListStream.Position);
            }
        }
示例#27
0
        public void BufferListStreamTest()
        {
            byte[] buffer = new byte[256];
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (byte)i;
            }

            ArraySegment <byte>[] segments = new ArraySegment <byte>[]
            {
                new ArraySegment <byte>(buffer, 0, 7),
                new ArraySegment <byte>(buffer, 7, 14),
                new ArraySegment <byte>(buffer, 21, 28),
                new ArraySegment <byte>(buffer, 49, 62),
                new ArraySegment <byte>(buffer, 111, 88),
                new ArraySegment <byte>(buffer, 199, 55),
                new ArraySegment <byte>(buffer, 254, 2),
            };

            BufferListStream stream = new BufferListStream(segments);

            Assert.True(stream.CanRead);
            Assert.True(stream.CanSeek);
            Assert.True(!stream.CanWrite);
            Assert.Equal(buffer.Length, stream.Length);

            stream.Seek(119, SeekOrigin.Begin);
            Assert.Equal(119, stream.Position);
            Assert.Equal(119, stream.ReadByte());

            stream.Seek(256, SeekOrigin.Begin);
            Assert.Equal(-1, stream.ReadByte());

            stream.Seek(-1, SeekOrigin.Current);
            Assert.Equal(255, stream.ReadByte());

            stream.Seek(-256, SeekOrigin.End);
            Assert.Equal(0, stream.ReadByte());

            try
            {
                stream.Seek(-198, SeekOrigin.Current);
                Assert.True(false, "Seek should fail with argument out of range exception");
            }
            catch (ArgumentOutOfRangeException)
            {
            }

            stream.Position = 120;

            // The position is 120 now
            stream.Seek(99, SeekOrigin.Current);
            Assert.Equal(219, stream.Position);
            Assert.Equal(219, stream.ReadByte());

            // The position is 220 now
            stream.Seek(-177, SeekOrigin.Current);
            Assert.Equal(43, stream.Position);
            Assert.Equal(43, stream.ReadByte());

            stream.Seek(0, SeekOrigin.Begin);
            for (int i = 0; i < buffer.Length; i++)
            {
                Assert.Equal(i, stream.Position);
                Assert.Equal(i, stream.ReadByte());
            }
            Assert.Equal(-1, stream.ReadByte());

            stream.Seek(25, SeekOrigin.Begin);
            byte[] tempBuffer = new byte[86];
            int    count      = stream.Read(tempBuffer, 0, tempBuffer.Length);

            Assert.Equal(tempBuffer.Length, count);
            Assert.Equal(111, stream.Position);
            Assert.Equal(111, stream.ReadByte());
            for (int i = 0; i < tempBuffer.Length; i++)
            {
                Assert.Equal(i + 25, tempBuffer[i]);
            }

            stream.Seek(25, SeekOrigin.Begin);
            tempBuffer = new byte[255];
            count      = stream.Read(tempBuffer, 0, tempBuffer.Length);
            Assert.Equal(231, count);
            Assert.Equal(-1, stream.ReadByte());

            stream.Seek(25, SeekOrigin.Begin);
            bool more = false;

            ArraySegment <byte>[] buffers = stream.ReadBuffers(229, true, out more);
            Assert.True(more);
            Assert.Equal(4, buffers.Length);
            Assert.Equal(24, buffers[0].Count);
            Assert.Equal(62, buffers[1].Count);
            Assert.Equal(88, buffers[2].Count);
            Assert.Equal(55, buffers[3].Count);
            Assert.Equal(254, stream.Position);

            stream.Seek(25, SeekOrigin.Begin);
            more    = false;
            buffers = stream.ReadBuffers(int.MaxValue, true, out more);
            Assert.False(more);
            Assert.Equal(5, buffers.Length);
            Assert.Equal(24, buffers[0].Count);
            Assert.Equal(62, buffers[1].Count);
            Assert.Equal(88, buffers[2].Count);
            Assert.Equal(55, buffers[3].Count);
            Assert.Equal(2, buffers[4].Count);
            Assert.Equal(256, stream.Position);

            stream.Seek(25, SeekOrigin.Begin);
            more    = false;
            buffers = stream.ReadBuffers(231, false, out more);
            Assert.False(more);
            Assert.Equal(25, stream.Position);

            stream.Dispose();
            try
            {
                stream.Position = 100;
                Assert.True(false, "Stream is disposed!!");
            }
            catch (ObjectDisposedException)
            {
            }
        }
示例#28
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="timeout"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task <long> ScheduleMessageInternalAsync(
            ServiceBusMessage message,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            var stopWatch = Stopwatch.StartNew();

            using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message))
            {
                var request = AmqpRequestMessage.CreateRequest(
                    ManagementConstants.Operations.ScheduleMessageOperation,
                    timeout,
                    null);

                if (_sendLink.TryGetOpenedObject(out SendingAmqpLink sendLink))
                {
                    request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name;
                }

                ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                var buffer = new BufferListStream(payload);
                ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length);

                var entry = new AmqpMap();
                {
                    entry[ManagementConstants.Properties.Message]   = value;
                    entry[ManagementConstants.Properties.MessageId] = message.MessageId;

                    if (!string.IsNullOrWhiteSpace(message.SessionId))
                    {
                        entry[ManagementConstants.Properties.SessionId] = message.SessionId;
                    }

                    if (!string.IsNullOrWhiteSpace(message.PartitionKey))
                    {
                        entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey;
                    }

                    if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey))
                    {
                        entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey;
                    }
                }

                request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                    entry
                };

                RequestResponseAmqpLink mgmtLink = await _managementLink.GetOrCreateAsync(
                    UseMinimum(_connectionScope.SessionTimeout,
                               timeout.CalculateRemaining(stopWatch.Elapsed)))
                                                   .ConfigureAwait(false);

                using AmqpMessage response = await mgmtLink.RequestAsync(
                          request.AmqpMessage,
                          timeout.CalculateRemaining(stopWatch.Elapsed))
                                             .ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
                stopWatch.Stop();

                AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response);

                if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                {
                    var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                    if (sequenceNumbers == null || sequenceNumbers.Length < 1)
                    {
                        throw new ServiceBusException(true, "Could not schedule message successfully.");
                    }

                    return(sequenceNumbers[0]);
                }
                else
                {
                    throw amqpResponseMessage.ToMessagingContractException();
                }
            }
        }
示例#29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="timeout"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task <long> ScheduleMessageInternalAsync(
            ServiceBusMessage message,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            var sendLink = default(SendingAmqpLink);

            try
            {
                using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message))
                {
                    var request = AmqpRequestMessage.CreateRequest(
                        ManagementConstants.Operations.ScheduleMessageOperation,
                        timeout,
                        null);

                    if (_sendLink.TryGetOpenedObject(out sendLink))
                    {
                        request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name;
                    }

                    ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                    var buffer = new BufferListStream(payload);
                    ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length);

                    var entry = new AmqpMap();
                    {
                        entry[ManagementConstants.Properties.Message]   = value;
                        entry[ManagementConstants.Properties.MessageId] = message.MessageId;

                        if (!string.IsNullOrWhiteSpace(message.SessionId))
                        {
                            entry[ManagementConstants.Properties.SessionId] = message.SessionId;
                        }

                        if (!string.IsNullOrWhiteSpace(message.PartitionKey))
                        {
                            entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey;
                        }

                        if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey))
                        {
                            entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey;
                        }
                    }

                    request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                        entry
                    };


                    AmqpResponseMessage amqpResponseMessage = await ManagementUtilities.ExecuteRequestResponseAsync(
                        _connectionScope,
                        _managementLink,
                        request,
                        timeout).ConfigureAwait(false);

                    cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                    if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                    {
                        var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                        if (sequenceNumbers == null || sequenceNumbers.Length < 1)
                        {
                            throw new ServiceBusException(true, "Could not schedule message successfully.");
                        }

                        return(sequenceNumbers[0]);
                    }
                    else
                    {
                        throw amqpResponseMessage.ToMessagingContractException();
                    }
                }
            }
            catch (Exception exception)
            {
                ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException(
                                                  exception,
                                                  sendLink?.GetTrackingId(),
                                                  null,
                                                  HasLinkCommunicationError(sendLink)))
                .Throw();

                throw; // will never be reached
            }
        }
示例#30
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="retryPolicy"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task <long> ScheduleMessageAsync(
            ServiceBusMessage message,
            ServiceBusRetryPolicy retryPolicy,
            string receiveLinkName = null,
            CancellationToken cancellationToken = default)
        {
            var failedAttemptCount = 0;
            var stopWatch          = Stopwatch.StartNew();

            try
            {
                TimeSpan tryTimeout = retryPolicy.CalculateTryTimeout(0);
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message))
                        {
                            var request = AmqpRequestMessage.CreateRequest(
                                ManagementConstants.Operations.ScheduleMessageOperation,
                                tryTimeout,
                                null);

                            if (receiveLinkName != null)
                            {
                                request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName;
                            }

                            ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                            var buffer = new BufferListStream(payload);
                            ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length);

                            var entry = new AmqpMap();
                            {
                                entry[ManagementConstants.Properties.Message]   = value;
                                entry[ManagementConstants.Properties.MessageId] = message.MessageId;

                                if (!string.IsNullOrWhiteSpace(message.SessionId))
                                {
                                    entry[ManagementConstants.Properties.SessionId] = message.SessionId;
                                }

                                if (!string.IsNullOrWhiteSpace(message.PartitionKey))
                                {
                                    entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey;
                                }

                                if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey))
                                {
                                    entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey;
                                }
                            }

                            request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                                entry
                            };


                            RequestResponseAmqpLink link = await ManagementLink.GetOrCreateAsync(
                                UseMinimum(ConnectionScope.SessionTimeout,
                                           tryTimeout.CalculateRemaining(stopWatch.Elapsed)))
                                                           .ConfigureAwait(false);

                            using AmqpMessage response = await link.RequestAsync(
                                      request.AmqpMessage,
                                      tryTimeout.CalculateRemaining(stopWatch.Elapsed))
                                                         .ConfigureAwait(false);

                            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
                            stopWatch.Stop();

                            AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response);

                            if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                            {
                                var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                                if (sequenceNumbers == null || sequenceNumbers.Length < 1)
                                {
                                    throw new ServiceBusException(true, "Could not schedule message successfully.");
                                }

                                return(sequenceNumbers[0]);
                            }
                            else
                            {
                                throw new Exception();

                                //throw response.ToMessagingContractException();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                        // Otherwise, mark the exception as active and break out of the loop.

                        ++failedAttemptCount;
                        TimeSpan?retryDelay = retryPolicy.CalculateRetryDelay(ex, failedAttemptCount);

                        if (retryDelay.HasValue && !ConnectionScope.IsDisposed && !cancellationToken.IsCancellationRequested)
                        {
                            ServiceBusEventSource.Log.ScheduleMessageError(EntityName, ex.Message);
                            await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);

                            tryTimeout = retryPolicy.CalculateTryTimeout(failedAttemptCount);
                            stopWatch.Reset();
                        }
                    }
                }
                // If no value has been returned nor exception thrown by this point,
                // then cancellation has been requested.

                throw new TaskCanceledException();
            }
            catch (Exception ex)
            {
                ServiceBusEventSource.Log.ScheduleMessageError(EntityName, ex.Message);
                throw;
            }
            finally
            {
                stopWatch.Stop();
                ServiceBusEventSource.Log.ScheduleMessageComplete(EntityName);
            }
        }