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));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
        }
예제 #8
0
        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);
            }
        }