internal static async Task DisposeMessageAsync(FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink, string lockToken, Outcome outcome, bool batchable) { var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await faultTolerantReceivingLink.GetReceivingLinkAsync().ConfigureAwait(false); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable, IotHubConnection.DefaultOperationTimeout).ConfigureAwait(false); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }
async Task DisposeMessageAsync(string lockToken, Outcome outcome) { var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await this.GetReceivingLinkAsync(); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable : true, timeout : this.OperationTimeout); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }
internal static async Task DisposeMessageAsync( FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink, string lockToken, Outcome outcome, bool batchable, CancellationToken cancellationToken) { Logging.Enter(faultTolerantReceivingLink, lockToken, outcome.DescriptorCode, batchable, nameof(DisposeMessageAsync)); try { cancellationToken.ThrowIfCancellationRequested(); ArraySegment <byte> deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await faultTolerantReceivingLink.GetReceivingLinkAsync().ConfigureAwait(false); disposeOutcome = await deviceBoundReceivingLink .DisposeMessageAsync( deliveryTag, outcome, batchable, cancellationToken) .ConfigureAwait(false); } catch (Exception exception) { Logging.Error(faultTolerantReceivingLink, exception, nameof(DisposeMessageAsync)); if (exception.IsFatal()) { throw; } throw ToIotHubClientContract(exception); } Logging.Info(faultTolerantReceivingLink, disposeOutcome.DescriptorCode, nameof(DisposeMessageAsync)); if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } } finally { Logging.Exit(faultTolerantReceivingLink, lockToken, outcome.DescriptorCode, batchable, nameof(DisposeMessageAsync)); } }
public static async Task <Outcome> DisposeMessageAsync(ReceivingAmqpLink receivingAmqpLink, string lockToken, Outcome outcome, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(receivingAmqpLink, timeout, $"{nameof(DisposeMessageAsync)}"); } ArraySegment <byte> deliveryTag = ConvertToDeliveryTag(lockToken); Outcome disposeOutcome = await receivingAmqpLink.DisposeMessageAsync(deliveryTag, outcome, batchable : true, timeout : timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(receivingAmqpLink, timeout, $"{nameof(DisposeMessageAsync)}"); } return(disposeOutcome); }
async Task DisposeMessageAsync(string lockToken, Outcome outcome, CancellationToken cancellationToken) { ArraySegment <byte> deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { // Currently, the same mechanism is used for sending feedback for C2D messages and events received by modules. // However, devices only support C2D messages (they cannot receive events), and modules only support receiving events // (they cannot receive C2D messages). So we use this to distinguish whether to dispose the message (i.e. send outcome on) // the DeviceBoundReceivingLink or the EventsReceivingLink. // If this changes (i.e. modules are able to receive C2D messages, or devices are able to receive telemetry), this logic // will have to be updated. ReceivingAmqpLink deviceBoundReceivingLink = !string.IsNullOrWhiteSpace(this.moduleId) ? await this.GetEventReceivingLinkAsync(cancellationToken).ConfigureAwait(false) : await this.GetDeviceBoundReceivingLinkAsync(cancellationToken).ConfigureAwait(false); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable : true, timeout : this.operationTimeout).ConfigureAwait(false); } catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException)) { throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { if (disposeOutcome.DescriptorCode == Rejected.Code) { var rejected = (Rejected)disposeOutcome; // Special treatment for NotFound amqp rejected error code in case of DisposeMessage if (rejected.Error != null && rejected.Error.Condition.Equals(AmqpErrorCode.NotFound)) { throw new DeviceMessageLockLostException(rejected.Error.Description); } } throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }
async Task RunClientAsync(string address) { AmqpConnectionFactory factory = new AmqpConnectionFactory(); factory.Settings.TransportProviders.Add( new TlsTransportProvider( new TlsTransportSettings() { CertificateValidationCallback = (a, b, c, d) => true }, AmqpVersion.V100)); AmqpConnection connection = await factory.OpenConnectionAsync(address); AmqpSession session = connection.CreateSession(new AmqpSessionSettings()); await session.OpenAsync(TimeSpan.FromSeconds(20)); SendingAmqpLink sLink = new SendingAmqpLink(session, AmqpUtils.GetLinkSettings(true, queue, SettleMode.SettleOnSend)); await sLink.OpenAsync(TimeSpan.FromSeconds(20)); AmqpMessage message = AmqpMessage.Create(new AmqpValue() { Value = "AmqpConnectionFactoryTest" }); Outcome outcome = await sLink.SendMessageAsync(message, EmptyBinary, NullBinary, TimeSpan.FromSeconds(10)); Assert.Equal(Accepted.Code, outcome.DescriptorCode); ReceivingAmqpLink rLink = new ReceivingAmqpLink(session, AmqpUtils.GetLinkSettings(false, queue, SettleMode.SettleOnDispose, 10)); await rLink.OpenAsync(TimeSpan.FromSeconds(20)); var receivedMessage = await rLink.ReceiveMessageAsync(TimeSpan.FromSeconds(20)); Assert.NotNull(receivedMessage); outcome = await rLink.DisposeMessageAsync(receivedMessage.DeliveryTag, new Accepted(), false, TimeSpan.FromSeconds(20)); Assert.Equal(Accepted.Code, outcome.DescriptorCode); await connection.CloseAsync(TimeSpan.FromSeconds(20)); }
internal async Task <AmqpIoTOutcome> DisposeMessageAsync(string lockToken, Outcome outcome, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, outcome, $"{nameof(DisposeMessageAsync)}"); } ArraySegment <byte> deliveryTag = ConvertToDeliveryTag(lockToken); Outcome disposeOutcome = await _receivingAmqpLink.DisposeMessageAsync( deliveryTag, outcome, batchable : true, timeout : timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, outcome, $"{nameof(DisposeMessageAsync)}"); } return(new AmqpIoTOutcome(disposeOutcome)); }
async Task DisposeMessageAsync(string lockToken, Outcome outcome) { var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await this.GetDeviceBoundReceivingLinkAsync(); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable : true, timeout : this.OperationTimeout); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { if (disposeOutcome.DescriptorCode == Rejected.Code) { var rejected = (Rejected)disposeOutcome; // Special treatment for NotFound amqp rejected error code in case of DisposeMessage if (rejected.Error != null && rejected.Error.Condition.Equals(AmqpErrorCode.NotFound)) { throw new DeviceMessageLockLostException(rejected.Error.Description); } } throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }