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); }
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); } }
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); } }
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); } }
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); }
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; }
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 }); }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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) { } }
/// <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(); } } }
/// <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 } }
/// <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); } }