private async Task DisposeMessageAsync(string lockToken, AmqpIotDisposeActions outcome, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, outcome, nameof(DisposeMessageAsync)); } 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. using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); AmqpIotOutcome disposeOutcome = await _amqpUnit.DisposeMessageAsync(lockToken, outcome, ctb.Token).ConfigureAwait(false); disposeOutcome.ThrowIfError(); } finally { if (Logging.IsEnabled) { Logging.Exit(this, outcome, nameof(DisposeMessageAsync)); } } }
public override async Task EnableTwinPatchAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(EnableTwinPatchAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); string correlationId = AmqpTwinMessageType.Put + Guid.NewGuid().ToString(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit .SendTwinMessageAsync(AmqpTwinMessageType.Put, correlationId, null, ctb.Token) .ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(EnableTwinPatchAsync)); } } }
public override async Task EnableEventReceiveAsync(bool isAnEdgeModule, CancellationToken cancellationToken) { // If an AMQP transport is opened as a module twin instead of an Edge module we need // to enable the deviceBound operations instead of the event receiver link if (isAnEdgeModule) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(EnableEventReceiveAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.EnableEventReceiveAsync(ctb.Token).ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(EnableEventReceiveAsync)); } } } else { await EnableReceiveMessageAsync(cancellationToken).ConfigureAwait(false); } }
public override async Task <Message> ReceiveAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(ReceiveAsync)); } Message message; while (true) { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_transportSettings.DefaultReceiveTimeout, cancellationToken); message = await _amqpUnit.ReceiveMessageAsync(ctb.Token).ConfigureAwait(false); if (message != null) { break; } } if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, cancellationToken, nameof(ReceiveAsync)); } return(message); }
public override async Task SendMethodResponseAsync(MethodResponseInternal methodResponse, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, methodResponse, cancellationToken, nameof(SendMethodResponseAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); AmqpIotOutcome amqpIotOutcome = await _amqpUnit .SendMethodResponseAsync(methodResponse, ctb.Token) .ConfigureAwait(false); if (amqpIotOutcome != null) { amqpIotOutcome.ThrowIfNotAccepted(); } } finally { if (Logging.IsEnabled) { Logging.Exit(this, methodResponse, cancellationToken, nameof(SendMethodResponseAsync)); } } }
public override async Task CloseAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, nameof(CloseAsync)); } lock (_lock) { _closed = true; } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.CloseAsync(ctb.Token).ConfigureAwait(false); } finally { OnTransportClosedGracefully(); if (Logging.IsEnabled) { Logging.Exit(this, nameof(CloseAsync)); } } }
public override async Task OpenAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(OpenAsync)); } cancellationToken.ThrowIfCancellationRequested(); lock (_lock) { if (_disposed) { return; } _closed = false; } try { using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.OpenAsync(ctb.Token).ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(OpenAsync)); } } }
private async Task <Twin> RoundTripTwinMessageAsync( AmqpTwinMessageType amqpTwinMessageType, TwinCollection reportedProperties, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(RoundTripTwinMessageAsync)); } string correlationId = amqpTwinMessageType + Guid.NewGuid().ToString(); Twin response = null; try { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource <Twin>(); _twinResponseCompletions[correlationId] = taskCompletionSource; using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.SendTwinMessageAsync(amqpTwinMessageType, correlationId, reportedProperties, ctb.Token).ConfigureAwait(false); Task <Twin> receivingTask = taskCompletionSource.Task; if (await Task .WhenAny(receivingTask, Task.Delay(TimeSpan.FromSeconds(ResponseTimeoutInSeconds), cancellationToken)) .ConfigureAwait(false) == receivingTask) { if (receivingTask.Exception?.InnerException != null) { throw receivingTask.Exception.InnerException; } // Task completed within timeout. // Consider that the task may have faulted or been canceled. // We re-await the task so that any exceptions/cancellation is re-thrown. response = await receivingTask.ConfigureAwait(false); } else { // Timeout happen throw new TimeoutException(); } } finally { _twinResponseCompletions.TryRemove(correlationId, out _); if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(RoundTripTwinMessageAsync)); } } return(response); }
public override async Task DisableTwinPatchAsync(CancellationToken cancellationToken) { try { Logging.Enter(this, cancellationToken, nameof(DisableTwinPatchAsync)); cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.DisableTwinLinksAsync(ctb.Token).ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(DisableTwinPatchAsync)); } } }
public override async Task EnableReceiveMessageAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(EnableReceiveMessageAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.EnableReceiveMessageAsync(ctb.Token).ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(EnableReceiveMessageAsync)); } } }
public override async Task SendEventAsync(IEnumerable <Message> messages, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, messages, cancellationToken, nameof(SendEventAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.SendEventsAsync(messages, ctb.Token).ConfigureAwait(false); } finally { if (Logging.IsEnabled) { Logging.Exit(this, messages, cancellationToken, nameof(SendEventAsync)); } } }
public override async Task SendEventAsync(Message message, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, message, cancellationToken, nameof(SendEventAsync)); } try { cancellationToken.ThrowIfCancellationRequested(); using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); AmqpIotOutcome amqpIotOutcome = await _amqpUnit.SendEventAsync(message, ctb.Token).ConfigureAwait(false); amqpIotOutcome?.ThrowIfNotAccepted(); } finally { if (Logging.IsEnabled) { Logging.Exit(this, message, cancellationToken, nameof(SendEventAsync)); } } }