Beispiel #1
0
        public override async Task OpenAsync(bool explicitOpen, CancellationToken cancellationToken)
        {
            if (!explicitOpen)
            {
                return;
            }

            await this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    await Task.WhenAll(
                        this.faultTolerantEventSendingLink.OpenAsync(this.openTimeout, cancellationToken),
                        this.faultTolerantDeviceBoundReceivingLink.OpenAsync(this.openTimeout, cancellationToken));
                    this.linkOpenedListener(this.faultTolerantEventSendingLink, new ConnectionEventArgs {
                        ConnectionKey = ConnectionKeys.AmqpTelemetry, ConnectionStatus = ConnectionStatus.Connected
                    });
                    this.linkOpenedListener(this.faultTolerantDeviceBoundReceivingLink, new ConnectionEventArgs {
                        ConnectionKey = ConnectionKeys.AmqpMessaging, ConnectionStatus = ConnectionStatus.Connected
                    });
                }
                catch (Exception exception)
                {
                    if (exception.IsFatal())
                    {
                        throw;
                    }

                    throw AmqpClientHelper.ToIotHubClientContract(exception);
                }
            }, cancellationToken);
        }
        public override Task EnableMethodsAsync(CancellationToken cancellationToken)
        {
#if WIP_C2D_METHODS_AMQP
            if (this.faultTolerantMethodSendingLink == null)
            {
                this.faultTolerantMethodSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateMethodSendingLinkAsync, this.IotHubConnection.CloseLink);
            }

            if (this.faultTolerantMethodReceivingLink == null)
            {
                this.faultTolerantMethodReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateMethodReceivingLinkAsync, this.IotHubConnection.CloseLink);
            }

            return(this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await Task.WhenAll(EnableSendingLinkAsync(cancellationToken), EnableReceivingLinkAsync(cancellationToken));
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken));
#else
            throw new NotImplementedException();
#endif
        }
Beispiel #3
0
        public override Task RecoverConnections(object link, ConnectionType connectionType, CancellationToken cancellationToken)
        {
            Func <Task> enableLinkAsyncFunc = null;

            object newlink = null;

            switch (connectionType)
            {
            case ConnectionType.AmqpMethodReceiving:
                this.faultTolerantMethodReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateMethodReceivingLinkAsync, this.IotHubConnection.CloseLink);
                enableLinkAsyncFunc = async() => await EnableMethodReceivingLinkAsync(cancellationToken);

                newlink = this.faultTolerantMethodReceivingLink;
                break;

            case ConnectionType.AmqpTwinReceiving:
                this.faultTolerantTwinReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateTwinReceivingLinkAsync, this.IotHubConnection.CloseLink);
                enableLinkAsyncFunc = async() => await EnableTwinReceivingLinkAsync(cancellationToken);

                newlink = this.faultTolerantTwinReceivingLink;
                break;

            case ConnectionType.AmqpMethodSending:
                this.faultTolerantMethodSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateMethodSendingLinkAsync, this.IotHubConnection.CloseLink);
                enableLinkAsyncFunc = async() => await EnableMethodSendingLinkAsync(cancellationToken);

                newlink = this.faultTolerantMethodSendingLink;
                break;

            case ConnectionType.AmqpTwinSending:
                this.faultTolerantTwinSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateTwinSendingLinkAsync, this.IotHubConnection.CloseLink);
                enableLinkAsyncFunc = async() => await EnableTwinSendingLinkAsync(cancellationToken);

                newlink = this.faultTolerantTwinSendingLink;
                break;

            default:
                return(Common.TaskConstants.Completed);
            }

            return(this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await enableLinkAsyncFunc();
                        this.linkOpenedListener(
                            newlink,
                            new ConnectionEventArgs {
                            ConnectionType = connectionType, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken));
        }
Beispiel #4
0
        public override async Task <Twin> SendTwinGetAsync(CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendTwinGetAsync)}");
            }
            try
            {
                await EnableTwinPatchAsync(cancellationToken).ConfigureAwait(false);

                AmqpMessage amqpMessage = AmqpMessage.Create();
                amqpMessage.MessageAnnotations.Map["operation"] = "GET";

                var response = await RoundTripTwinMessage(amqpMessage, cancellationToken).ConfigureAwait(false);

                return(TwinFromResponse(response));
            }
            catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
            {
                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendTwinGetAsync)}");
                }
            }
        }
        public override async Task <Twin> SendTwinGetAsync(CancellationToken cancellationToken)
        {
            Outcome outcome;

            try
            {
                await EnableTwinAsync(cancellationToken);

                SendingAmqpLink eventSendingLink = await this.GetTwinSendingLinkAsync(cancellationToken);

                // This is test code and will be re-written in future commits

                AmqpMessage getTwinMessage   = AmqpMessage.Create();
                string      getCorrelationId = Guid.NewGuid().ToString();
                getTwinMessage.Properties.CorrelationId            = getCorrelationId;
                getTwinMessage.MessageAnnotations.Map["operation"] = "GET";

                outcome = await eventSendingLink.SendMessageAsync(getTwinMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()), AmqpConstants.NullBinary, this.operationTimeout);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            return(null);
        }
Beispiel #6
0
        public override async Task SendTwinPatchAsync(TwinCollection reportedProperties, CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, reportedProperties, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendTwinPatchAsync)}");
            }
            try
            {
                await EnableTwinPatchAsync(cancellationToken).ConfigureAwait(false);

                var body       = JsonConvert.SerializeObject(reportedProperties);
                var bodyStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(body));

                var amqpMessage = AmqpMessage.Create(bodyStream, true);
                amqpMessage.MessageAnnotations.Map["operation"] = "PATCH";
                amqpMessage.MessageAnnotations.Map["resource"]  = "/properties/reported";
                amqpMessage.MessageAnnotations.Map["version"]   = null;

                var response = await RoundTripTwinMessage(amqpMessage, cancellationToken).ConfigureAwait(false);

                VerifyResponseMessage(response);
            }
            catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
            {
                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, reportedProperties, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendTwinPatchAsync)}");
                }
            }
        }
Beispiel #7
0
        async Task <Outcome> SendAmqpMethodResponseAsync(AmqpMessage amqpMessage, CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, amqpMessage, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendAmqpMethodResponseAsync)}");
            }
            Outcome outcome;

            try
            {
                SendingAmqpLink methodRespSendingLink = await this.GetMethodSendingLinkAsync(cancellationToken).ConfigureAwait(false);

                outcome = await methodRespSendingLink.SendMessageAsync(amqpMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()), AmqpConstants.NullBinary, this.operationTimeout).ConfigureAwait(false);
            }
            catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
            {
                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, amqpMessage, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(SendAmqpMethodResponseAsync)}");
                }
            }

            return(outcome);
        }
Beispiel #8
0
        public override async Task SendTwinPatchAsync(TwinCollection reportedProperties, CancellationToken cancellationToken)
        {
            try
            {
                await EnableTwinPatchAsync(cancellationToken);

                var body       = JsonConvert.SerializeObject(reportedProperties);
                var bodyStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(body));

                var amqpMessage = AmqpMessage.Create(bodyStream, true);
                amqpMessage.MessageAnnotations.Map["operation"] = "PATCH";
                amqpMessage.MessageAnnotations.Map["resource"]  = "/properties/reported";
                amqpMessage.MessageAnnotations.Map["version"]   = null;

                await RoundTripTwinMessage(amqpMessage, cancellationToken);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
        }
Beispiel #9
0
        public override async Task <Message> ReceiveAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Message message = null;

            AmqpMessage amqpMessage;

            try
            {
                ReceivingAmqpLink deviceBoundReceivingLink = await this.GetDeviceBoundReceivingLinkAsync(cancellationToken).ConfigureAwait(false);

                amqpMessage = await deviceBoundReceivingLink.ReceiveMessageAsync(timeout).ConfigureAwait(false);
            }
            catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
            {
                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            if (amqpMessage != null)
            {
                message = new Message(amqpMessage)
                {
                    LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString()
                };
            }
            else
            {
                message = null;
            }

            return(message);
        }
        public override async Task OpenAsync(bool explicitOpen, CancellationToken cancellationToken)
        {
            if (!explicitOpen)
            {
                return;
            }

            await this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    await Task.WhenAll(
                        this.faultTolerantEventSendingLink.OpenAsync(this.openTimeout, cancellationToken),
                        this.faultTolerantDeviceBoundReceivingLink.OpenAsync(this.openTimeout, cancellationToken));
                }
                catch (Exception exception)
                {
                    if (exception.IsFatal())
                    {
                        throw;
                    }

                    throw AmqpClientHelper.ToIotHubClientContract(exception);
                }
            }, cancellationToken);
        }
        public override Task RecoverConnections(object link, CancellationToken cancellationToken)
        {
            Func <Task> enableMethodLinkAsyncFunc = null;

            var amqpLink = link as AmqpLink;

            if (amqpLink == null)
            {
                return(Common.TaskConstants.Completed);
            }

            if (amqpLink.IsReceiver)
            {
                this.faultTolerantMethodReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateMethodReceivingLinkAsync, this.IotHubConnection.CloseLink);
                enableMethodLinkAsyncFunc             = async() => await EnableMethodReceivingLinkAsync(cancellationToken);
            }
            else
            {
                this.faultTolerantMethodSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateMethodSendingLinkAsync, this.IotHubConnection.CloseLink);
                enableMethodLinkAsyncFunc           = async() => await EnableMethodSendingLinkAsync(cancellationToken);
            }

            return(this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await enableMethodLinkAsyncFunc();
                        this.linkOpenedListener(
                            this.faultTolerantMethodSendingLink,
                            new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpMethodSending, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                        this.linkOpenedListener(
                            this.faultTolerantMethodReceivingLink,
                            new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpMethodReceiving, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken));
        }
Beispiel #12
0
        public override async Task EnableTwinPatchAsync(CancellationToken cancellationToken)
        {
            try
            {
                if (Logging.IsEnabled)
                {
                    Logging.Enter(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(EnableTwinPatchAsync)}");
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (this.faultTolerantTwinSendingLink == null)
                {
                    this.faultTolerantTwinSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateTwinSendingLinkAsync, OnAmqpLinkClose);
                }

                if (this.faultTolerantTwinReceivingLink == null)
                {
                    this.faultTolerantTwinReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateTwinReceivingLinkAsync, OnAmqpLinkClose);
                }

                try
                {
                    if (this.onDesiredStatePatchListener != null)
                    {
                        await Task.WhenAll(EnableTwinSendingLinkAsync(cancellationToken), EnableTwinReceivingLinkAsync(cancellationToken)).ConfigureAwait(false);

                        // generate new guid for reconnection
                        twinConnectionCorrelationId = Guid.NewGuid().ToString("N");
                    }
                }
                catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
                {
                    throw AmqpClientHelper.ToIotHubClientContract(exception);
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(EnableTwinPatchAsync)}");
                }
            }
        }
Beispiel #13
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);
            }
        }
        public override Task RecoverConnections(object link, CancellationToken cancellationToken)
        {
#if WIP_C2D_METHODS_AMQP
            Func <Task> enableMethodLinkAsyncFunc = null;

            var amqpLink = link as AmqpLink;
            if (amqpLink == null)
            {
                return(Common.TaskConstants.Completed);
            }

            if (amqpLink.IsReceiver)
            {
                this.faultTolerantMethodReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateMethodReceivingLinkAsync, this.IotHubConnection.CloseLink);
                enableMethodLinkAsyncFunc             = async() => await EnableReceivingLinkAsync(cancellationToken);
            }
            else
            {
                this.faultTolerantMethodSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateMethodSendingLinkAsync, this.IotHubConnection.CloseLink);
                enableMethodLinkAsyncFunc           = async() => await EnableSendingLinkAsync(cancellationToken);
            }

            return(this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await enableMethodLinkAsyncFunc();
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken));
#else
            throw new NotImplementedException();
#endif
        }
Beispiel #15
0
        public override async Task OpenAsync(CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(OpenAsync)}");
            }

            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                await this.faultTolerantEventSendingLink.OpenAsync(this.openTimeout, cancellationToken).ConfigureAwait(false);

                if (string.IsNullOrWhiteSpace(this.moduleId))
                {
                    await this.faultTolerantDeviceBoundReceivingLink.OpenAsync(this.openTimeout, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
            {
                Exception newException = AmqpClientHelper.ToIotHubClientContract(exception);

                if (newException != exception)
                {
                    throw newException;
                }
                else
                {
                    // Maintain the original stack.
                    throw;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(OpenAsync)}");
                }
            }
        }
        async Task <Outcome> SendAmqpMessageAsync(AmqpMessage amqpMessage)
        {
            Outcome outcome;

            try
            {
                SendingAmqpLink eventSendingLink = await this.GetEventSendingLinkAsync();

                outcome = await eventSendingLink.SendMessageAsync(amqpMessage, IotHubConnection.GetNextDeliveryTag(ref this.eventsDeliveryTag), AmqpConstants.NullBinary, this.OperationTimeout);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            return(outcome);
        }
Beispiel #17
0
        async Task <Outcome> SendAmqpMethodResponseAsync(AmqpMessage amqpMessage, CancellationToken cancellationToken)
        {
            Outcome outcome;

            try
            {
                SendingAmqpLink methodRespSendingLink = await this.GetMethodSendingLinkAsync(cancellationToken);

                outcome = await methodRespSendingLink.SendMessageAsync(amqpMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()), AmqpConstants.NullBinary, this.operationTimeout);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            return(outcome);
        }
Beispiel #18
0
        public override async Task EnableTwinPatchAsync(CancellationToken cancellationToken)
        {
            if (this.faultTolerantTwinSendingLink == null)
            {
                this.faultTolerantTwinSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateTwinSendingLinkAsync, this.IotHubConnection.CloseLink);
            }

            if (this.faultTolerantTwinReceivingLink == null)
            {
                this.faultTolerantTwinReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateTwinReceivingLinkAsync, this.IotHubConnection.CloseLink);
            }

            await this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await Task.WhenAll(EnableTwinSendingLinkAsync(cancellationToken), EnableTwinReceivingLinkAsync(cancellationToken));
                        this.linkOpenedListener(
                            this.faultTolerantTwinSendingLink,
                            new ConnectionEventArgs {
                            ConnectionType = ConnectionType.AmqpTwinSending, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                        this.linkOpenedListener(
                            this.faultTolerantTwinReceivingLink,
                            new ConnectionEventArgs {
                            ConnectionType = ConnectionType.AmqpTwinReceiving, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                        // generate new guid for reconnection
                        twinConnectionCorrelationId = Guid.NewGuid().ToString("N");
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken);
        }
        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);
            }
        }
        protected override async Task OnOpenAsync(bool explicitOpen)
        {
            if (!explicitOpen)
            {
                return;
            }

            try
            {
                await Task.WhenAll(
                    this.faultTolerantEventSendingLink.OpenAsync(this.OpenTimeout),
                    this.faultTolerantDeviceBoundReceivingLink.OpenAsync(this.OpenTimeout));
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
        }
Beispiel #21
0
        public override async Task <Twin> SendTwinGetAsync(CancellationToken cancellationToken)
        {
            try
            {
                await EnableTwinPatchAsync(cancellationToken);

                AmqpMessage amqpMessage = AmqpMessage.Create();
                amqpMessage.MessageAnnotations.Map["operation"] = "GET";

                var response = await RoundTripTwinMessage(amqpMessage, cancellationToken);

                return(TwinFromResponse(response));
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
        }
Beispiel #22
0
        public override async Task <Message> ReceiveAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            Message message = null;

            await this.HandleTimeoutCancellation(async() =>
            {
                AmqpMessage amqpMessage;
                try
                {
                    ReceivingAmqpLink deviceBoundReceivingLink = await this.GetDeviceBoundReceivingLinkAsync(cancellationToken);
                    amqpMessage = await deviceBoundReceivingLink.ReceiveMessageAsync(timeout);
                }
                catch (Exception exception)
                {
                    if (exception.IsFatal())
                    {
                        throw;
                    }

                    throw AmqpClientHelper.ToIotHubClientContract(exception);
                }

                if (amqpMessage != null)
                {
                    message = new Message(amqpMessage)
                    {
                        LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString()
                    };
                }
                else
                {
                    message = null;
                }
            }, cancellationToken);

            return(message);
        }
        public override async Task EnableMethodsAsync(CancellationToken cancellationToken)
        {
            if (this.faultTolerantMethodSendingLink == null)
            {
                this.faultTolerantMethodSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateMethodSendingLinkAsync, this.IotHubConnection.CloseLink);
            }

            if (this.faultTolerantMethodReceivingLink == null)
            {
                this.faultTolerantMethodReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateMethodReceivingLinkAsync, this.IotHubConnection.CloseLink);
            }

            await this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await Task.WhenAll(EnableMethodSendingLinkAsync(cancellationToken), EnableMethodReceivingLinkAsync(cancellationToken));
                        this.linkOpenedListener(
                            this.faultTolerantMethodSendingLink,
                            new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpMethodSending, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                        this.linkOpenedListener(
                            this.faultTolerantMethodReceivingLink,
                            new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpMethodReceiving, ConnectionStatus = ConnectionStatus.Connected, ConnectionStatusChangeReason = ConnectionStatusChangeReason.Connection_Ok
                        });
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken);
        }
Beispiel #24
0
        public override async Task EnableTwinPatchAsync(CancellationToken cancellationToken)
        {
#if WIP_C2D_METHODS_AMQP
            if (this.faultTolerantTwinSendingLink == null)
            {
                this.faultTolerantTwinSendingLink = new Client.FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateTwinSendingLinkAsync, this.IotHubConnection.CloseLink);
            }

            if (this.faultTolerantTwinReceivingLink == null)
            {
                this.faultTolerantTwinReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateTwinReceivingLinkAsync, this.IotHubConnection.CloseLink);
            }

            await this.HandleTimeoutCancellation(async() =>
            {
                try
                {
                    if (this.messageListener != null)
                    {
                        await Task.WhenAll(EnableTwinSendingLinkAsync(cancellationToken), EnableTwinReceivingLinkAsync(cancellationToken));
                        this.linkOpenedListener(this.faultTolerantTwinSendingLink, new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpTwinSending, ConnectionStatus = ConnectionStatus.Connected
                        });
                        this.linkOpenedListener(this.faultTolerantTwinReceivingLink, new ConnectionEventArgs {
                            ConnectionKey = ConnectionKeys.AmqpTwinReceiving, ConnectionStatus = ConnectionStatus.Connected
                        });
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    throw AmqpClientHelper.ToIotHubClientContract(ex);
                }
            }, cancellationToken);
#else
            throw new NotImplementedException();
#endif
        }
        protected async override Task <Message> OnReceiveAsync(TimeSpan timeout)
        {
            AmqpMessage amqpMessage;

            try
            {
                ReceivingAmqpLink deviceBoundReceivingLink = await this.GetDeviceBoundReceivingLinkAsync();

                amqpMessage = await deviceBoundReceivingLink.ReceiveMessageAsync(timeout);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            Message message;

            if (amqpMessage != null)
            {
                message = new Message(amqpMessage)
                {
                    LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString()
                };
            }
            else
            {
                message = null;
            }

            return(message);
        }
Beispiel #26
0
        public override async Task EnableEventReceiveAsync(CancellationToken cancellationToken)
        {
            try
            {
                if (Logging.IsEnabled)
                {
                    Logging.Enter(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(EnableEventReceiveAsync)}");
                }

                cancellationToken.ThrowIfCancellationRequested();

                if (this.faultTolerantEventReceivingLink == null)
                {
                    this.faultTolerantEventReceivingLink = new Client.FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateEventReceivingLinkAsync, OnAmqpLinkClose);
                }

                try
                {
                    if (this.eventReceivedListener != null)
                    {
                        await this.faultTolerantEventReceivingLink.OpenAsync(this.openTimeout, cancellationToken).ConfigureAwait(false);
                    }
                }
                catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException))
                {
                    throw AmqpClientHelper.ToIotHubClientContract(exception);
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, cancellationToken, $"{nameof(AmqpTransportHandler)}.{nameof(EnableEventReceiveAsync)}");
                }
            }
        }