diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d9b3b0eb4e..343a0c7e71 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,3 @@ # Track1 .NET Azure IoT Hub and DPS SDKs -* @drwill-ms @timtay-microsoft @abhipsaMisra @azabbasi @jamdavi @andyk-ms @brycewang-microsoft +* @drwill-ms @timtay-microsoft @abhipsaMisra @azabbasi @andyk-ms @brycewang-microsoft diff --git a/iothub/device/src/DeviceClient.cs b/iothub/device/src/DeviceClient.cs index 01910c541c..8e4e027171 100644 --- a/iothub/device/src/DeviceClient.cs +++ b/iothub/device/src/DeviceClient.cs @@ -319,7 +319,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy) /// /// /// You cannot reject or abandon messages over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// A cancellation token to cancel the operation. /// Thrown when the operation has been canceled. The inner exception will be . @@ -333,7 +333,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy) /// /// /// You cannot reject or abandon messages over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The received message or null if there was no message until the specified time has elapsed. public Task ReceiveAsync(TimeSpan timeout) => InternalClient.ReceiveAsync(timeout); @@ -383,7 +383,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot abandon a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message lockToken. public Task AbandonAsync(string lockToken) => InternalClient.AbandonAsync(lockToken); @@ -393,7 +393,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot abandon a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message lockToken. /// A cancellation token to cancel the operation. @@ -405,7 +405,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot abandon a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message to abandon. public Task AbandonAsync(Message message) => InternalClient.AbandonAsync(message); @@ -415,7 +415,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot abandon a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message to abandon. /// A cancellation token to cancel the operation. @@ -427,7 +427,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot reject a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message lockToken. public Task RejectAsync(string lockToken) => InternalClient.RejectAsync(lockToken); @@ -449,7 +449,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot reject a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message. public Task RejectAsync(Message message) => InternalClient.RejectAsync(message); @@ -459,7 +459,7 @@ public Task SetReceiveMessageHandlerAsync(ReceiveMessageCallback messageHandler, /// /// /// You cannot reject a message over MQTT protocol. - /// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. + /// For more details, see https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle. /// /// The message to reject. /// A cancellation token to cancel the operation. diff --git a/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs b/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs index 5d9681be70..aaf9245af0 100644 --- a/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs +++ b/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs @@ -10,7 +10,8 @@ using Microsoft.Azure.Devices.Client.Exceptions; using Microsoft.Azure.Devices.Client.Extensions; using Microsoft.Azure.Devices.Client.Transport.AmqpIot; -using Microsoft.Azure.Devices.Shared; +using System.Collections.Generic; +using System.Linq; namespace Microsoft.Azure.Devices.Client.Transport.Amqp { diff --git a/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs b/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs index 67430620d5..5571cd551f 100644 --- a/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs +++ b/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs @@ -25,7 +25,7 @@ internal class AmqpTransportHandler : TransportHandler protected AmqpUnit _amqpUnit; private readonly Action _onDesiredStatePatchListener; private readonly object _lock = new object(); - private readonly ConcurrentDictionary> _twinResponseCompletions = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary> _twinResponseCompletions = new ConcurrentDictionary>(); private bool _closed; static AmqpTransportHandler() diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs index d547c487ef..0a6e4406b1 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs @@ -33,7 +33,9 @@ using Newtonsoft.Json; #if NET5_0 + using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource; + #else using TaskCompletionSource = Microsoft.Azure.Devices.Shared.TaskCompletionSource; #endif @@ -112,7 +114,8 @@ internal sealed class MqttTransportHandler : TransportHandler, IMqttIotHubEventH private readonly Func> _channelFactory; private readonly Queue _completionQueue; private readonly MqttIotHubAdapterFactory _mqttIotHubAdapterFactory; - private readonly QualityOfService _qos; + private readonly QualityOfService _qosSendPacketToService; + private readonly QualityOfService _qosReceivePacketFromService; private readonly bool _retainMessagesAcrossSessions; private readonly object _syncRoot = new object(); private readonly RetryPolicy _closeRetryPolicy; @@ -173,7 +176,8 @@ internal MqttTransportHandler( _deviceboundMessageFilter = string.Format(CultureInfo.InvariantCulture, DeviceBoundMessagesTopicFilter, iotHubConnectionString.DeviceId); _deviceboundMessagePrefix = string.Format(CultureInfo.InvariantCulture, DeviceBoundMessagesTopicPrefix, iotHubConnectionString.DeviceId); - _qos = settings.PublishToServerQoS; + _qosSendPacketToService = settings.PublishToServerQoS; + _qosReceivePacketFromService = settings.ReceivingQoS; // If the CleanSession flag is set to false, C2D messages will be retained across device sessions, i.e. the device // will receive the C2D messages that were sent to it while it was disconnected. @@ -299,7 +303,7 @@ public override async Task ReceiveAsync(CancellationToken cancellationT } await WaitUntilC2dMessageArrivesAsync(cancellationToken).ConfigureAwait(false); - return ProcessMessage(); + return ProcessC2dMessage(); } finally { @@ -338,7 +342,7 @@ public override async Task ReceiveAsync(TimeoutHelper timeoutHelper) using var cts = new CancellationTokenSource(timeout); await WaitUntilC2dMessageArrivesAsync(cts.Token).ConfigureAwait(false); - return ProcessMessage(); + return ProcessC2dMessage(); } finally { @@ -347,20 +351,20 @@ public override async Task ReceiveAsync(TimeoutHelper timeoutHelper) } } - private Message ProcessMessage() + private Message ProcessC2dMessage() { Message message = null; try { if (Logging.IsEnabled) - Logging.Enter(this, message, $"Will begin processing received C2D message, queue size={_messageQueue.Count}", nameof(ProcessMessage)); + Logging.Enter(this, message, $"Will begin processing received C2D message, queue size={_messageQueue.Count}", nameof(ProcessC2dMessage)); lock (_syncRoot) { if (_messageQueue.TryDequeue(out message)) { - if (_qos == QualityOfService.AtLeastOnce) + if (_qosReceivePacketFromService == QualityOfService.AtLeastOnce) { _completionQueue.Enqueue(message.LockToken); } @@ -374,7 +378,7 @@ private Message ProcessMessage() finally { if (Logging.IsEnabled) - Logging.Exit(this, message, $"Processed received C2D message with Id={message?.MessageId}", nameof(ProcessMessage)); + Logging.Exit(this, message, $"Processed received C2D message with Id={message?.MessageId}", nameof(ProcessC2dMessage)); } } @@ -398,7 +402,7 @@ public override async Task CompleteAsync(string lockToken, CancellationToken can cancellationToken.ThrowIfCancellationRequested(); EnsureValidState(); - if (_qos == QualityOfService.AtMostOnce) + if (_qosReceivePacketFromService == QualityOfService.AtMostOnce) { throw new IotHubException("Complete is not allowed for QoS 0.", isTransient: false); } @@ -565,7 +569,7 @@ private async Task HandleIncomingMessagesAsync() if (Logging.IsEnabled) Logging.Enter(this, "Process C2D message via callback", nameof(HandleIncomingMessagesAsync)); - Message message = ProcessMessage(); + Message message = ProcessC2dMessage(); // We are intentionally not awaiting _deviceMessageReceivedListener callback. // This is a user-supplied callback that isn't required to be awaited by us. We can simply invoke it and continue. @@ -652,7 +656,7 @@ private async Task HandleIncomingEventMessageAsync(Message message) // Add the endpoint as a SystemProperty message.SystemProperties.Add(MessageSystemPropertyNames.InputName, inputName); - if (_qos == QualityOfService.AtLeastOnce) + if (_qosReceivePacketFromService == QualityOfService.AtLeastOnce) { lock (_syncRoot) { @@ -833,7 +837,7 @@ public override async Task EnableMethodsAsync(CancellationToken cancellationToke // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_001: `EnableMethodsAsync` shall subscribe using the '$iothub/methods/POST/' topic filter. // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_002: `EnableMethodsAsync` shall wait for a SUBACK for the subscription request. // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_003: `EnableMethodsAsync` shall return failure if the subscription request fails. - await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(MethodPostTopicFilter, QualityOfService.AtMostOnce))).ConfigureAwait(true); + await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(MethodPostTopicFilter, _qosReceivePacketFromService))).ConfigureAwait(true); } public override async Task DisableMethodsAsync(CancellationToken cancellationToken) @@ -855,7 +859,7 @@ public override async Task EnableEventReceiveAsync(bool isAnEdgeModule, Cancella // Codes_SRS_CSHARP_MQTT_TRANSPORT_33_021: `EnableEventReceiveAsync` shall subscribe using the 'devices/{0}/modules/{1}/' topic filter. // Codes_SRS_CSHARP_MQTT_TRANSPORT_33_022: `EnableEventReceiveAsync` shall wait for a SUBACK for the subscription request. // Codes_SRS_CSHARP_MQTT_TRANSPORT_33_023: `EnableEventReceiveAsync` shall return failure if the subscription request fails. - await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(_receiveEventMessageFilter, _qos))).ConfigureAwait(true); + await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(_receiveEventMessageFilter, _qosReceivePacketFromService))).ConfigureAwait(true); } public override async Task DisableEventReceiveAsync(bool isAnEdgeModule, CancellationToken cancellationToken) @@ -897,7 +901,7 @@ public override async Task EnableTwinPatchAsync(CancellationToken cancellationTo // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_010: `EnableTwinPatchAsync` shall subscribe using the '$iothub/twin/PATCH/properties/desired/#' topic filter. // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_011: `EnableTwinPatchAsync` shall wait for a SUBACK on the subscription request. // Codes_SRS_CSHARP_MQTT_TRANSPORT_18_012: `EnableTwinPatchAsync` shall return failure if the subscription request fails. - await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(TwinPatchTopicFilter, QualityOfService.AtMostOnce))).ConfigureAwait(true); + await _channel.WriteAsync(new SubscribePacket(0, new SubscriptionRequest(TwinPatchTopicFilter, _qosReceivePacketFromService))).ConfigureAwait(true); if (Logging.IsEnabled) Logging.Exit(this, cancellationToken, nameof(EnableTwinPatchAsync)); @@ -1076,7 +1080,7 @@ private async Task SubscribeCloudToDeviceMessagesAsync() if (TryStateTransition(TransportState.Open, TransportState.Subscribing)) { await _channel - .WriteAsync(new SubscribePacket(0, new SubscriptionRequest(_deviceboundMessageFilter, QualityOfService.AtLeastOnce))) + .WriteAsync(new SubscribePacket(0, new SubscriptionRequest(_deviceboundMessageFilter, _qosReceivePacketFromService))) .ConfigureAwait(true); if (TryStateTransition(TransportState.Subscribing, TransportState.Receiving) @@ -1095,7 +1099,7 @@ private Task SubscribeTwinResponsesAsync() 0, new SubscriptionRequest( TwinResponseTopicFilter, - QualityOfService.AtMostOnce))); + _qosReceivePacketFromService))); } private bool ParseResponseTopic(string topicName, out int status) diff --git a/iothub/service/src/JobProperties.cs b/iothub/service/src/JobProperties.cs index fa2c705128..e708e8d5e2 100644 --- a/iothub/service/src/JobProperties.cs +++ b/iothub/service/src/JobProperties.cs @@ -8,7 +8,8 @@ namespace Microsoft.Azure.Devices { /// /// Contains properties of a Job. - /// See online documentation for more infomration. + /// See online documentation + /// for more infomration. /// public class JobProperties { diff --git a/iothub/service/src/Microsoft.Azure.Devices.csproj b/iothub/service/src/Microsoft.Azure.Devices.csproj index c06a99befc..691665fd53 100644 --- a/iothub/service/src/Microsoft.Azure.Devices.csproj +++ b/iothub/service/src/Microsoft.Azure.Devices.csproj @@ -174,6 +174,6 @@ - + diff --git a/readme.md b/readme.md index 32220f393d..095c1d079c 100644 --- a/readme.md +++ b/readme.md @@ -205,12 +205,13 @@ This table shows previous LTS releases and end dates. | Release | LTS Start Date | Maintenance End Date | LTS End Date | | :----------------------------------------------------------------------------------------------------------------------------: | :------------: | :------------------: | :----------: | +| [2022-01-18](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18-patch4) patch 4 of 2021-03-18 | 2022-01-18 | 2022-03-18 | 2024-03-17 | | [2021-10-19](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18-patch3) patch 3 of 2021-03-18 | 2021-10-19 | 2022-03-18 | 2024-03-17 | | [2021-8-12](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18_patch2) patch 2 of 2021-03-18 | 2021-08-12 | 2022-03-18 | 2024-03-17 | -| [2021-8-10](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19_patch2) patch 2 of 2021-08-19 | 2021-08-10 | 2021-08-19 | 2023-08-19 | +| [2021-8-10](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19_patch2) patch 2 of 2020-08-19 | 2020-08-10 | 2021-08-19 | 2023-08-19 | | [2021-6-23](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18_patch1) patch 1 of 2021-03-18 | 2020-06-23 | 2022-03-18 | 2024-03-17 | | [2021-3-18](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18) | 2020-03-18 | 2022-03-18 | 2024-03-17 | -| [2020-9-23](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19_patch1) patch 1 of 2021-08-19 | 2020-09-23 | 2021-08-19 | 2023-08-19 | +| [2020-9-23](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19_patch1) patch 1 of 2020-08-19 | 2020-09-23 | 2021-08-19 | 2023-08-19 | | [2020-8-19](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19) | 2020-08-19 | 2021-08-19 | 2023-08-19 | | [2020-4-3](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-1-31_patch1) patch 1 of 2020-01-31 | 2020-04-03 | 2021-01-30 | 2023-01-30 | | [2020-1-31](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-1-31) | 2020-01-31 | 2021-01-30 | 2023-01-30 |