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); } }
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 ArraySegment <byte> PatternMatch() { using var messageStream = amqpMessage.ToStream(); return(messageStream switch { BufferListStream bufferListStream => bufferListStream.ReadBytes((int)stream.Length), _ => throw new InvalidOperationException() });
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 }); }
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 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); }
/// <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); } }