protected virtual async Task <DateTime> OnRenewLockAsync(string lockToken) { DateTime lockedUntilUtc = DateTime.MinValue; try { // Create an AmqpRequest Message to renew lock AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.RenewLockOperation, this.OperationTimeout, null); requestMessage.Map[ManagementConstants.Properties.LockTokens] = new[] { new Guid(lockToken) }; AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false); if (response.StatusCode == AmqpResponseStatusCode.OK) { IEnumerable <DateTime> lockedUntilUtcTimes = response.GetValue <IEnumerable <DateTime> >(ManagementConstants.Properties.Expirations); lockedUntilUtc = lockedUntilUtcTimes.First(); } else { throw response.ToMessagingContractException(); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception); } return(lockedUntilUtc); }
/// <summary> /// /// </summary> /// <param name="operation"></param> /// <param name="scope"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task RunOperation( Func <TimeSpan, Task> operation, TransportConnectionScope scope, CancellationToken cancellationToken) { var failedAttemptCount = 0; TimeSpan tryTimeout = CalculateTryTimeout(0); if (IsServerBusy && tryTimeout < ServerBusyBaseSleepTime) { // We are in a server busy state before we start processing. // Since ServerBusyBaseSleepTime > remaining time for the operation, we don't wait for the entire Sleep time. await Task.Delay(tryTimeout, cancellationToken).ConfigureAwait(false); throw new ServiceBusException( ServerBusyExceptionMessage, ServiceBusFailureReason.ServiceBusy); } while (!cancellationToken.IsCancellationRequested) { if (IsServerBusy) { await Task.Delay(ServerBusyBaseSleepTime, cancellationToken).ConfigureAwait(false); } try { await operation(tryTimeout).ConfigureAwait(false); return; } catch (Exception ex) { Exception activeEx = AmqpExceptionHelper.TranslateException(ex); // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop. // Otherwise, throw the translated exception. ++failedAttemptCount; TimeSpan?retryDelay = CalculateRetryDelay(activeEx, failedAttemptCount); if (retryDelay.HasValue && !scope.IsDisposed && !cancellationToken.IsCancellationRequested) { Logger.RunOperationExceptionEncountered(activeEx.ToString()); await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false); tryTimeout = CalculateTryTimeout(failedAttemptCount); } else { ExceptionDispatchInfo.Capture(activeEx) .Throw(); } } } // If no value has been returned nor exception thrown by this point, // then cancellation has been requested. throw new TaskCanceledException(); }
public void MismatchingExceptionNotTranslated() { var argumentException = new ArgumentException(); EventHubsException newException; var translated = AmqpExceptionHelper.TryTranslateToRetriableException(argumentException, out newException); Assert.False(translated, "TryTranslateToRetriableException returned true"); }
public void InvalidOperationExceptionWithoutClosingMessageNotTranslated() { var invalidOperationException = new InvalidOperationException("this is some other error"); EventHubsException newException; var translated = AmqpExceptionHelper.TryTranslateToRetriableException(invalidOperationException, out newException); Assert.False(translated, "TryTranslateToRetriableException returned true"); }
protected virtual async Task <IList <Message> > OnPeekAsync(long fromSequenceNumber, int messageCount = 1) { try { AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.PeekMessageOperation, this.OperationTimeout, null); requestMessage.Map[ManagementConstants.Properties.FromSequenceNumber] = fromSequenceNumber; requestMessage.Map[ManagementConstants.Properties.MessageCount] = messageCount; if (!string.IsNullOrWhiteSpace(this.SessionId)) { requestMessage.Map[ManagementConstants.Properties.SessionId] = this.SessionId; } List <Message> messages = new List <Message>(); AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false); if (response.StatusCode == AmqpResponseStatusCode.OK) { Message message = null; var messageList = response.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages); foreach (AmqpMap entry in messageList) { var payload = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message]; AmqpMessage amqpMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true); message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); messages.Add(message); } if (message != null) { this.LastPeekedSequenceNumber = message.SystemProperties.SequenceNumber; } return(messages); } else if (response.StatusCode == AmqpResponseStatusCode.NoContent || (response.StatusCode == AmqpResponseStatusCode.NotFound && Equals(AmqpClientConstants.MessageNotFoundError, response.GetResponseErrorCondition()))) { return(messages); } else { throw response.ToMessagingContractException(); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception); } }
/// <summary> /// Gets a particular session object identified by <paramref name="sessionId"/> that can be used to receive messages for that sessionId. /// </summary> /// <param name="sessionId">The sessionId present in all its messages.</param> /// <param name="serverWaitTime">Amount of time for which the call should wait to fetch the next session.</param> /// <remarks>All plugins registered on <see cref="SessionClient"/> will be applied to each <see cref="MessageSession"/> that is accepted. /// Individual sessions can further register additional plugins.</remarks> /// <returns>A session object.</returns> public async Task <IMessageSession> AcceptMessageSessionAsync(string sessionId, TimeSpan serverWaitTime) { MessagingEventSource.Log.AmqpSessionClientAcceptMessageSessionStart( this.ClientId, this.EntityPath, this.ReceiveMode, this.PrefetchCount, sessionId); var session = new MessageSession( this.EntityPath, this.EntityType, this.ReceiveMode, this.ServiceBusConnection, this.CbsTokenProvider, this.RetryPolicy, this.PrefetchCount, sessionId, true); try { await this.RetryPolicy.RunOperation( async() => { await session.GetSessionReceiverLinkAsync(serverWaitTime).ConfigureAwait(false); }, serverWaitTime) .ConfigureAwait(false); } catch (Exception exception) { MessagingEventSource.Log.AmqpSessionClientAcceptMessageSessionException( this.ClientId, this.EntityPath, exception); await session.CloseAsync().ConfigureAwait(false); throw AmqpExceptionHelper.GetClientException(exception); } MessagingEventSource.Log.AmqpSessionClientAcceptMessageSessionStop( this.ClientId, this.EntityPath, session.SessionIdInternal); session.UpdateClientId(ClientEntity.GenerateClientId(nameof(MessageSession), $"{this.EntityPath}_{session.SessionId}")); // Register plugins on the message session. foreach (var serviceBusPlugin in this.RegisteredPlugins) { session.RegisterPlugin(serviceBusPlugin); } return(session); }
public void InvalidOperationExceptionWithClosingMessageTranslated() { var invalidOperationException = new InvalidOperationException("Can't create session when the connection is closing."); EventHubsException newException; var translated = AmqpExceptionHelper.TryTranslateToRetriableException(invalidOperationException, out newException); Assert.True(translated, "TryTranslateToRetriableException returned false"); Assert.True(newException.IsTransient, "newException.IsTransient == false"); Assert.True(newException.InnerException == invalidOperationException, "newException.InnerException != invalidOperationException"); }
protected virtual async Task <IList <Message> > OnReceiveAsync(int maxMessageCount, TimeSpan serverWaitTime) { ReceivingAmqpLink receiveLink = null; try { TimeoutHelper timeoutHelper = new TimeoutHelper(serverWaitTime, true); receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); IEnumerable <AmqpMessage> amqpMessages = null; bool hasMessages = await Task.Factory.FromAsync( (c, s) => receiveLink.BeginReceiveRemoteMessages(maxMessageCount, DefaultBatchFlushInterval, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndReceiveMessages(a, out amqpMessages), this).ConfigureAwait(false); if (receiveLink.TerminalException != null) { throw receiveLink.TerminalException; } if (hasMessages && amqpMessages != null) { IList <Message> brokeredMessages = null; foreach (var amqpMessage in amqpMessages) { if (brokeredMessages == null) { brokeredMessages = new List <Message>(); } if (this.ReceiveMode == ReceiveMode.ReceiveAndDelete) { receiveLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome); } Message message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); brokeredMessages.Add(message); } return(brokeredMessages); } return(null); } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception, receiveLink?.GetTrackingId()); } }
public async Task <EventHubPartitionRuntimeInformation> GetPartitionRuntimeInformationAsync(string partitionId) { RequestResponseAmqpLink requestLink = await link.GetOrCreateAsync( TimeSpan.FromSeconds(AmqpClientConstants.AmqpSessionTimeoutInSeconds)).ConfigureAwait(false); // Create request and attach token. AmqpMessage request = CreateGetPartitionRuntimeInformationRequest(partitionId); request.ApplicationProperties.Map[AmqpClientConstants.ManagementSecurityTokenKey] = await GetTokenString().ConfigureAwait(false); AmqpMessage response = await requestLink.RequestAsync(request, eventHubClient.ConnectionStringBuilder.OperationTimeout).ConfigureAwait(false); int statusCode = (int)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode]; string statusDescription = (string)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription]; if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK) { AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(response, (AmqpResponseStatusCode)statusCode); Error error = new Error { Condition = errorCondition, Description = statusDescription }; throw AmqpExceptionHelper.ToMessagingContract(error); } AmqpMap infoMap = null; if (response.ValueBody != null) { infoMap = response.ValueBody.Value as AmqpMap; } if (infoMap == null) { throw new InvalidOperationException($"Return type mismatch in GetPartitionRuntimeInformationAsync. Response returned NULL or response isn't AmqpMap."); } return(new EventHubPartitionRuntimeInformation() { Type = (string)infoMap[new MapKey(AmqpClientConstants.EntityTypeName)], Path = (string)infoMap[new MapKey(AmqpClientConstants.EntityNameKey)], PartitionId = (string)infoMap[new MapKey(AmqpClientConstants.PartitionNameKey)], BeginSequenceNumber = (long)infoMap[new MapKey(AmqpClientConstants.ManagementPartitionBeginSequenceNumber)], LastEnqueuedSequenceNumber = (long)infoMap[new MapKey(AmqpClientConstants.ManagementPartitionLastEnqueuedSequenceNumber)], LastEnqueuedOffset = (string)infoMap[new MapKey(AmqpClientConstants.ManagementPartitionLastEnqueuedOffset)], LastEnqueuedTimeUtc = (DateTime)infoMap[new MapKey(AmqpClientConstants.ManagementPartitionLastEnqueuedTimeUtc)], IsEmpty = (bool)infoMap[new MapKey(AmqpClientConstants.ManagementPartitionRuntimeInfoPartitionIsEmpty)] }); }
public async Task <EventHubPartitionRuntimeInformation> GetPartitionRuntimeInformationAsync(string partitionId) { RequestResponseAmqpLink requestLink = await this.link.GetOrCreateAsync(TimeSpan.FromMinutes(1)).ConfigureAwait(false); // Create request and attach token. var request = this.CreateGetPartitionRuntimeInformationRequest(partitionId); request.ApplicationProperties.Map[AmqpClientConstants.ManagementSecurityTokenKey] = await GetTokenString().ConfigureAwait(false); var response = await requestLink.RequestAsync(request, TimeSpan.FromMinutes(1)).ConfigureAwait(false); int statusCode = (int)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode]; string statusDescription = (string)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription]; if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK) { AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(response, (AmqpResponseStatusCode)statusCode); Error error = new Error { Condition = errorCondition, Description = statusDescription }; throw AmqpExceptionHelper.ToMessagingContract(error); } AmqpMap infoMap = null; if (response.ValueBody != null) { infoMap = response.ValueBody.Value as AmqpMap; } if (infoMap == null) { throw new InvalidOperationException($"Return type mismatch in GetPartitionRuntimeInformationAsync. Response returned NULL or response isn't AmqpMap."); } return(new EventHubPartitionRuntimeInformation() { Type = (string)infoMap[new MapKey("type")], Path = (string)infoMap[new MapKey("name")], PartitionId = (string)infoMap[new MapKey("partition")], BeginSequenceNumber = (long)infoMap[new MapKey("begin_sequence_number")], LastEnqueuedSequenceNumber = (long)infoMap[new MapKey("last_enqueued_sequence_number")], LastEnqueuedOffset = (string)infoMap[new MapKey("last_enqueued_offset")], LastEnqueuedTimeUtc = (DateTime)infoMap[new MapKey("last_enqueued_time_utc")] }); }
public async Task <EventHubRuntimeInformation> GetRuntimeInformationAsync() { RequestResponseAmqpLink requestLink = await link.GetOrCreateAsync( TimeSpan.FromSeconds(AmqpClientConstants.AmqpSessionTimeoutInSeconds)).ConfigureAwait(false); // Create request and attach token. AmqpMessage request = CreateGetRuntimeInformationRequest(); request.ApplicationProperties.Map[AmqpClientConstants.ManagementSecurityTokenKey] = await GetTokenString().ConfigureAwait(false); AmqpMessage response = await requestLink.RequestAsync(request, eventHubClient.ConnectionStringBuilder.OperationTimeout).ConfigureAwait(false); int statusCode = (int)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode]; string statusDescription = (string)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription]; if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK) { AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(response, (AmqpResponseStatusCode)statusCode); Error error = new Error { Condition = errorCondition, Description = statusDescription }; throw AmqpExceptionHelper.ToMessagingContract(error); } AmqpMap infoMap = null; if (response.ValueBody != null) { infoMap = response.ValueBody.Value as AmqpMap; } if (infoMap == null) { throw new InvalidOperationException($"Return type mismatch in GetRuntimeInformationAsync. Response returned NULL or response isn't AmqpMap."); } return(new EventHubRuntimeInformation() { Type = (string)infoMap[new MapKey("type")], Path = (string)infoMap[new MapKey("name")], CreatedAt = (DateTime)infoMap[new MapKey("created_at")], PartitionCount = (int)infoMap[new MapKey("partition_count")], PartitionIds = (string[])infoMap[new MapKey("partition_ids")], }); }
protected virtual async Task <IList <Message> > OnReceiveBySequenceNumberAsync(IEnumerable <long> sequenceNumbers) { List <Message> messages = new List <Message>(); try { AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.ReceiveBySequenceNumberOperation, this.OperationTimeout, null); requestMessage.Map[ManagementConstants.Properties.SequenceNumbers] = sequenceNumbers.ToArray(); requestMessage.Map[ManagementConstants.Properties.ReceiverSettleMode] = (uint)(this.ReceiveMode == ReceiveMode.ReceiveAndDelete ? 0 : 1); AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false); if (response.StatusCode == AmqpResponseStatusCode.OK) { IEnumerable <AmqpMap> amqpMapList = response.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages); foreach (AmqpMap entry in amqpMapList) { ArraySegment <byte> payload = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message]; AmqpMessage amqpMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true); Message message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); Guid lockToken; if (entry.TryGetValue(ManagementConstants.Properties.LockToken, out lockToken)) { message.SystemProperties.LockTokenGuid = lockToken; this.requestResponseLockedMessages.AddOrUpdate(lockToken, message.SystemProperties.LockedUntilUtc); } messages.Add(message); } } else { throw response.ToMessagingContractException(); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception); } return(messages); }
async Task DisposeMessageRequestResponseAsync(IEnumerable <Guid> lockTokens, DispositionStatus dispositionStatus) { try { // Create an AmqpRequest Message to update disposition AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.UpdateDispositionOperation, this.OperationTimeout, null); requestMessage.Map[ManagementConstants.Properties.LockTokens] = lockTokens.ToArray(); requestMessage.Map[ManagementConstants.Properties.DispositionStatus] = dispositionStatus.ToString().ToLowerInvariant(); AmqpResponseMessage amqpResponseMessage = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false); if (amqpResponseMessage.StatusCode != AmqpResponseStatusCode.OK) { throw amqpResponseMessage.ToMessagingContractException(); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception); } }
async Task OnSendAsync(IList <Message> messageList) { TimeoutHelper timeoutHelper = new TimeoutHelper(this.OperationTimeout, true); using (AmqpMessage amqpMessage = AmqpMessageConverter.BatchSBMessagesAsAmqpMessage(messageList, true)) { SendingAmqpLink amqpLink = null; try { amqpLink = await this.SendLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); if (amqpLink.Settings.MaxMessageSize.HasValue) { ulong size = (ulong)amqpMessage.SerializedMessageSize; if (size > amqpLink.Settings.MaxMessageSize.Value) { // TODO: Add MessageSizeExceededException throw new NotImplementedException("MessageSizeExceededException: " + Resources.AmqpMessageSizeExceeded.FormatForUser(amqpMessage.DeliveryId.Value, size, amqpLink.Settings.MaxMessageSize.Value)); ////throw Fx.Exception.AsError(new MessageSizeExceededException( ////Resources.AmqpMessageSizeExceeded.FormatForUser(amqpMessage.DeliveryId.Value, size, amqpLink.Settings.MaxMessageSize.Value))); } } Outcome outcome = await amqpLink.SendMessageAsync(amqpMessage, this.GetNextDeliveryTag(), AmqpConstants.NullBinary, timeoutHelper.RemainingTime()).ConfigureAwait(false); if (outcome.DescriptorCode != Accepted.Code) { Rejected rejected = (Rejected)outcome; throw Fx.Exception.AsError(AmqpExceptionHelper.ToMessagingContractException(rejected.Error)); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception, amqpLink?.GetTrackingId()); } } }
public async Task <object> Start() { RequestResponseAmqpLink requestLink = await this.client.link.GetOrCreateAsync(TimeSpan.FromMinutes(1)); ApplicationProperties properties = new ApplicationProperties(); properties.Map[AmqpClientConstants.ManagementOperationKey] = this.md.Operation.Name; // generate message sections containing the arguments // convert custom-type parameters if needed object bodyValue = null; AmqpMap bodyMap = null; for (int i = 0; i < this.argCount; i++) { ManagementParamAttribute paramAttribute = this.md.Parameters[i]; object value = SerializationHelper.ToAmqp(this.md.ParameterTypes[i].Serializable, this.mcm.InArgs[i]); if (paramAttribute.Location == ManagementParamLocation.ApplicationProperties) { properties.Map[paramAttribute.Name] = value; } else if (paramAttribute.Location == ManagementParamLocation.MapBody) { if (bodyMap == null) { bodyMap = new AmqpMap(); } bodyMap[new MapKey(paramAttribute.Name)] = value; } else { bodyValue = value; } } // Upsert link RequestProperties to ApplicationProperties foreach (var requestProperty in requestLink.RequestProperties) { properties.Map[requestProperty.Key] = requestProperty.Value; } this.request = AmqpMessage.Create(new AmqpValue { Value = bodyMap ?? bodyValue }); this.request.ApplicationProperties = properties; this.response = await requestLink.RequestAsync(request, TimeSpan.FromMinutes(1)); int statusCode = (int)this.response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode]; string statusDescription = (string)this.response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription]; if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK) { AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(this.response, (AmqpResponseStatusCode)statusCode); Error error = new Error { Condition = errorCondition, Description = statusDescription }; throw new AmqpException(error); } object returnValue = null; if (this.response.ValueBody != null) { returnValue = this.response.ValueBody.Value; } if (md.ReturnType.HasValue && returnValue != null) { Type expected = md.ReturnType.Type; SerializableType serializable = md.ReturnType.Serializable; if (serializable == null) { // must be a generic parameter expected = mcm.GenericTypes[md.ReturnType.Type.GenericParameterPosition]; serializable = expected.GetSerializable(); } returnValue = SerializationHelper.FromAmqp(serializable, returnValue); if (!expected.IsAssignableFrom(returnValue.GetType())) { throw new InvalidOperationException($"Return type mismatch in {mcm.MethodBase.Name}. Expect {expected.Name} Actual {returnValue.GetType().Name}"); } } return(returnValue); }
async Task DisposeMessagesAsync(IEnumerable <Guid> lockTokens, Outcome outcome) { TimeoutHelper timeoutHelper = new TimeoutHelper(this.OperationTimeout, true); IList <ArraySegment <byte> > deliveryTags = this.ConvertLockTokensToDeliveryTags(lockTokens); ReceivingAmqpLink receiveLink = null; try { receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); Task <Outcome>[] disposeMessageTasks = new Task <Outcome> [deliveryTags.Count]; int i = 0; foreach (ArraySegment <byte> deliveryTag in deliveryTags) { disposeMessageTasks[i++] = Task.Factory.FromAsync( (c, s) => receiveLink.BeginDisposeMessage(deliveryTag, outcome, true, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndDisposeMessage(a), this); } Outcome[] outcomes = await Task.WhenAll(disposeMessageTasks).ConfigureAwait(false); Error error = null; foreach (Outcome item in outcomes) { var disposedOutcome = item.DescriptorCode == Rejected.Code && ((error = ((Rejected)item).Error) != null) ? item : null; if (disposedOutcome != null) { if (error.Condition.Equals(AmqpErrorCode.NotFound)) { if (this.isSessionReceiver) { throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } else { throw new MessageLockLostException(Resources.MessageLockLost); } } throw AmqpExceptionHelper.ToMessagingContractException(error); } } } catch (Exception exception) { if (exception is OperationCanceledException && receiveLink != null && receiveLink.State != AmqpObjectState.Opened) { if (this.isSessionReceiver) { throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } else { throw new MessageLockLostException(Resources.MessageLockLost); } } throw AmqpExceptionHelper.GetClientException(exception); } }