From ad62351b9764583983d152c75d217eb92e4f0cdc Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Fri, 1 May 2026 15:38:28 -0700 Subject: [PATCH 1/8] Re-add steps for publishing Microsoft.Azure.Devices.Shared package bits (#3532) --- vsts/release.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vsts/release.yaml b/vsts/release.yaml index f562874392..36d59992f7 100644 --- a/vsts/release.yaml +++ b/vsts/release.yaml @@ -15,6 +15,13 @@ parameters: - true - false default: false +- name: publishShared + displayName: Publish Microsoft.Azure.Devices.Shared package + type: string + values: + - true + - false + default: false - name: publishDpsDevice displayName: Publish Microsoft.Azure.Devices.Provisioning.Client package type: string @@ -62,6 +69,11 @@ jobs: dotnet pack --configuration Release $(Build.SourcesDirectory)/iothub/service/src/Microsoft.Azure.Devices.csproj -o $(Build.SourcesDirectory)/_nupkgs/ -p:IncludeSymbols=false displayName: Build and pack Microsoft.Azure.Devices.Client condition: eq(${{ parameters.publishHubService }}, 'true') + + - bash: | + dotnet pack --configuration Release $(Build.SourcesDirectory)/shared/src/Microsoft.Azure.Devices.Shared.csproj -o $(Build.SourcesDirectory)/_nupkgs/ -p:IncludeSymbols=false + displayName: Build and pack Microsoft.Azure.Devices.Shared + condition: eq(${{ parameters.publishShared }}, 'true') - bash: | dotnet pack --configuration Release $(Build.SourcesDirectory)/provisioning/device/src/Microsoft.Azure.Devices.Provisioning.Client.csproj -o $(Build.SourcesDirectory)/_nupkgs/ -p:IncludeSymbols=false From 6097889d2afdd19f815053479bf0a60a982d466e Mon Sep 17 00:00:00 2001 From: Ewerton Scaboro da Silva Date: Sun, 3 May 2026 22:40:55 -0700 Subject: [PATCH 2/8] Point Horton e2e at iot-sdks-e2e-fx master (#3534) * restore Horton E2E pipeline config for ewertons/horton-fixes Use staged pipeline format, correct GitHub endpoint, and reference ewertons/horton-fixes branch of iot-sdks-e2e-fx. * Point Horton e2e at iot-sdks-e2e-fx master Switch Horton.FrameworkRef and the e2e_fx repository ref from ewertons/horton-fixes to master so this branch consumes the merged Horton fixes from the framework's mainline. * Re-trigger Horton e2e build * Trigger Horton CI: pick up e2e-fx master ModuleClient cache fix * Trigger Horton CI: pick up e2e-fx EnableTwin cache-invalidation fix --------- Co-authored-by: ewertons --- vsts/horton-e2e.yaml | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/vsts/horton-e2e.yaml b/vsts/horton-e2e.yaml index 2833102b48..9db7af593b 100644 --- a/vsts/horton-e2e.yaml +++ b/vsts/horton-e2e.yaml @@ -12,7 +12,31 @@ resources: type: github name: Azure/iot-sdks-e2e-fx ref: refs/heads/master - endpoint: 'GitHub OAuth - az-iot-builder-01' + endpoint: 'azure-iot-sdk-python-github' -jobs: -- template: vsts/templates/jobs-gate-csharp.yaml@e2e_fx +stages: +- stage: setup + jobs: + - job: create_azure_resources + pool: + vmImage: 'windows-latest' + steps: + - template: vsts/templates/steps-create-azure-resources.yaml@e2e_fx + +- stage: build_and_test + dependsOn: setup + jobs: + - template: vsts/templates/jobs-gate-csharp.yaml@e2e_fx + +- stage: cleanup + dependsOn: + - setup + - build_and_test + condition: always() + jobs: + - job: destroy_azure_resource_group + condition: always() + pool: + vmImage: 'ubuntu-24.04' + steps: + - template: vsts/templates/steps-destroy-azure-resources.yaml@e2e_fx \ No newline at end of file From 99c47d9071ce1180e5c9a45bd766d57778eb7db9 Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Wed, 10 Jun 2026 14:07:28 -0700 Subject: [PATCH 3/8] to revert netstandard to revert Revert "netstandard to revert" This reverts commit 98d04f795c724187777cef5225a622c1b0dada16. autoack todo to revert ? ack issue? Revert "ack issue?" This reverts commit 3c93ee834f574822320de77a9c9eb1270dba7438. Revert "?" This reverts commit a4e499386672d48f694e061e7baeaf49b2b08676. Revert "todo to revert" This reverts commit b2a2e0634f4ebfe99d9fff8a0b0ab677c968c637. Revert "autoack" This reverts commit 35dd83de0932fd1789df6c96939a75f2d7f94824. Reapply "netstandard to revert" This reverts commit 089d51a5588f83f4c088209640e50f4f7f937d81. Revert "netstandard to revert" This reverts commit 98d04f795c724187777cef5225a622c1b0dada16. --- vsts/horton-e2e.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsts/horton-e2e.yaml b/vsts/horton-e2e.yaml index 9db7af593b..bbb5021706 100644 --- a/vsts/horton-e2e.yaml +++ b/vsts/horton-e2e.yaml @@ -1,6 +1,6 @@ variables: Horton.FrameworkRoot: $(Agent.BuildDirectory)/e2e-fx - Horton.FrameworkRef: master + Horton.FrameworkRef: timtay/temp Horton.Language: csharp Horton.Repo: $(Build.Repository.Uri) Horton.Commit: $(Build.SourceBranch) From ab48bc8835ba32d1423b7b7296535bcac2cfbfae Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Fri, 12 Jun 2026 16:02:08 -0700 Subject: [PATCH 4/8] manual acks --- .../src/Transport/Mqtt/MqttTransportHandler.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs index bea2b43233..54f9a28734 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs @@ -1281,7 +1281,6 @@ private static Message ProcessC2DMessage(MqttApplicationMessageReceivedEventArgs private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { - receivedEventArgs.AutoAcknowledge = false; string topic = receivedEventArgs.ApplicationMessage.Topic; if (topic.StartsWith(_deviceBoundMessagesTopic, StringComparison.InvariantCulture)) @@ -1300,14 +1299,17 @@ private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEven else if (topic.StartsWith(TwinDesiredPropertiesPatchTopic, StringComparison.InvariantCulture)) { HandleReceivedDesiredPropertiesUpdateRequest(receivedEventArgs); + await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); } else if (topic.StartsWith(TwinResponseTopic, StringComparison.InvariantCulture)) { HandleTwinResponse(receivedEventArgs); + await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); } else if (topic.StartsWith(DirectMethodsRequestTopic, StringComparison.InvariantCulture)) { HandleReceivedDirectMethodRequest(receivedEventArgs); + await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); } else if (topic.StartsWith(_moduleEventMessageTopic, StringComparison.InvariantCulture) || topic.StartsWith(_edgeModuleInputEventsTopic, StringComparison.InvariantCulture)) @@ -1315,6 +1317,7 @@ private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEven // This works regardless of if the event is on a particular Edge module input or if // the module is not an Edge module. await HandleIncomingEventMessageAsync(receivedEventArgs).ConfigureAwait(false); + await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); } else if (Logging.IsEnabled) { @@ -1352,9 +1355,6 @@ private async Task HandleReceivedCloudToDeviceMessageAsync(Message receivedCloud private void HandleReceivedDirectMethodRequest(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { - // This message is always QoS 0, so no ack will be sent. - receivedEventArgs.AutoAcknowledge = true; - byte[] payload = receivedEventArgs.ApplicationMessage.Payload.ToArray(); string[] tokens = Regex.Split(receivedEventArgs.ApplicationMessage.Topic, "/", RegexOptions.Compiled); @@ -1372,8 +1372,6 @@ private void HandleReceivedDirectMethodRequest(MqttApplicationMessageReceivedEve private void HandleReceivedDesiredPropertiesUpdateRequest(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { - // This message is always QoS 0, so no ack will be sent. - receivedEventArgs.AutoAcknowledge = true; var twinProperties = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(receivedEventArgs.ApplicationMessage.Payload.ToArray()), JsonSerializerSettingsInitializer.GetJsonSerializerSettings()); _onDesiredStatePatchListener.Invoke(twinProperties); @@ -1381,9 +1379,6 @@ private void HandleReceivedDesiredPropertiesUpdateRequest(MqttApplicationMessage private void HandleTwinResponse(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { - // This message is always QoS 0, so no ack will be sent. - receivedEventArgs.AutoAcknowledge = true; - if (ParseResponseTopic(receivedEventArgs.ApplicationMessage.Topic, out string receivedRequestId, out int status, out long version)) { byte[] payloadBytes = receivedEventArgs.ApplicationMessage.Payload.ToArray() ?? Array.Empty(); @@ -1496,8 +1491,6 @@ private void RemoveOldOperations(object state) private async Task HandleIncomingEventMessageAsync(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { - receivedEventArgs.AutoAcknowledge = true; - using var iotHubMessage = new Message(receivedEventArgs.ApplicationMessage.Payload.ToArray()); // The MqttTopic is in the format - devices/deviceId/modules/moduleId/inputs/inputName From 927e78e172646e787de7e253ff68a21bdfebbd11 Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Fri, 12 Jun 2026 16:03:07 -0700 Subject: [PATCH 5/8] notes --- vsts/horton-e2e.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsts/horton-e2e.yaml b/vsts/horton-e2e.yaml index bbb5021706..175ca7788f 100644 --- a/vsts/horton-e2e.yaml +++ b/vsts/horton-e2e.yaml @@ -1,6 +1,6 @@ variables: Horton.FrameworkRoot: $(Agent.BuildDirectory)/e2e-fx - Horton.FrameworkRef: timtay/temp + Horton.FrameworkRef: timtay/temp # This is deliberately not targeting main because the main branch builds for an older version of .NET than this branch of the azure-iot-sdk-csharp repo targets Horton.Language: csharp Horton.Repo: $(Build.Repository.Uri) Horton.Commit: $(Build.SourceBranch) From 1e69e07fb0924a31e37b5dfea8f4a1041debfeaf Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Fri, 12 Jun 2026 16:27:01 -0700 Subject: [PATCH 6/8] Version bump --- iothub/device/src/Microsoft.Azure.Devices.Client.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj index 1798469fc3..2ec8d5ff1a 100644 --- a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj +++ b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj @@ -33,7 +33,7 @@ - 1.43.0-edgeLts + 1.43.1-edgeLts Microsoft Azure IoT Device Client SDK True True From 0e1a87bdec8b710f1c29ada2994baa3fbce3a9cf Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Fri, 12 Jun 2026 17:17:49 -0700 Subject: [PATCH 7/8] ack first? --- iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs index 54f9a28734..d8433c90eb 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs @@ -1298,26 +1298,26 @@ private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEven } else if (topic.StartsWith(TwinDesiredPropertiesPatchTopic, StringComparison.InvariantCulture)) { - HandleReceivedDesiredPropertiesUpdateRequest(receivedEventArgs); await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); + HandleReceivedDesiredPropertiesUpdateRequest(receivedEventArgs); } else if (topic.StartsWith(TwinResponseTopic, StringComparison.InvariantCulture)) { - HandleTwinResponse(receivedEventArgs); await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); + HandleTwinResponse(receivedEventArgs); } else if (topic.StartsWith(DirectMethodsRequestTopic, StringComparison.InvariantCulture)) { - HandleReceivedDirectMethodRequest(receivedEventArgs); await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); + HandleReceivedDirectMethodRequest(receivedEventArgs); } else if (topic.StartsWith(_moduleEventMessageTopic, StringComparison.InvariantCulture) || topic.StartsWith(_edgeModuleInputEventsTopic, StringComparison.InvariantCulture)) { // This works regardless of if the event is on a particular Edge module input or if // the module is not an Edge module. - await HandleIncomingEventMessageAsync(receivedEventArgs).ConfigureAwait(false); await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); + await HandleIncomingEventMessageAsync(receivedEventArgs).ConfigureAwait(false); } else if (Logging.IsEnabled) { From 8fe7610a93bdf4fc13eeb96f9a75a2111d5946f1 Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Mon, 22 Jun 2026 11:02:39 -0700 Subject: [PATCH 8/8] Fix bug where message properties were not populated if they were module to module messages --- .../src/Microsoft.Azure.Devices.Client.csproj | 2 +- .../src/Transport/Mqtt/MqttTransportHandler.cs | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj index 2ec8d5ff1a..46be631def 100644 --- a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj +++ b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj @@ -33,7 +33,7 @@ - 1.43.1-edgeLts + 1.43.2-edgeLts Microsoft Azure IoT Device Client SDK True True diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs index d8433c90eb..90242d14aa 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs @@ -1281,6 +1281,7 @@ private static Message ProcessC2DMessage(MqttApplicationMessageReceivedEventArgs private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { + receivedEventArgs.AutoAcknowledge = false; string topic = receivedEventArgs.ApplicationMessage.Topic; if (topic.StartsWith(_deviceBoundMessagesTopic, StringComparison.InvariantCulture)) @@ -1298,17 +1299,14 @@ private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEven } else if (topic.StartsWith(TwinDesiredPropertiesPatchTopic, StringComparison.InvariantCulture)) { - await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); HandleReceivedDesiredPropertiesUpdateRequest(receivedEventArgs); } else if (topic.StartsWith(TwinResponseTopic, StringComparison.InvariantCulture)) { - await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); HandleTwinResponse(receivedEventArgs); } else if (topic.StartsWith(DirectMethodsRequestTopic, StringComparison.InvariantCulture)) { - await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); HandleReceivedDirectMethodRequest(receivedEventArgs); } else if (topic.StartsWith(_moduleEventMessageTopic, StringComparison.InvariantCulture) @@ -1316,7 +1314,6 @@ private async Task HandleReceivedMessageAsync(MqttApplicationMessageReceivedEven { // This works regardless of if the event is on a particular Edge module input or if // the module is not an Edge module. - await receivedEventArgs.AcknowledgeAsync(CancellationToken.None); await HandleIncomingEventMessageAsync(receivedEventArgs).ConfigureAwait(false); } else if (Logging.IsEnabled) @@ -1355,6 +1352,9 @@ private async Task HandleReceivedCloudToDeviceMessageAsync(Message receivedCloud private void HandleReceivedDirectMethodRequest(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { + // This message is always QoS 0, so no ack will be sent. + receivedEventArgs.AutoAcknowledge = true; + byte[] payload = receivedEventArgs.ApplicationMessage.Payload.ToArray(); string[] tokens = Regex.Split(receivedEventArgs.ApplicationMessage.Topic, "/", RegexOptions.Compiled); @@ -1372,6 +1372,8 @@ private void HandleReceivedDirectMethodRequest(MqttApplicationMessageReceivedEve private void HandleReceivedDesiredPropertiesUpdateRequest(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { + // This message is always QoS 0, so no ack will be sent. + receivedEventArgs.AutoAcknowledge = true; var twinProperties = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(receivedEventArgs.ApplicationMessage.Payload.ToArray()), JsonSerializerSettingsInitializer.GetJsonSerializerSettings()); _onDesiredStatePatchListener.Invoke(twinProperties); @@ -1379,6 +1381,9 @@ private void HandleReceivedDesiredPropertiesUpdateRequest(MqttApplicationMessage private void HandleTwinResponse(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { + // This message is always QoS 0, so no ack will be sent. + receivedEventArgs.AutoAcknowledge = true; + if (ParseResponseTopic(receivedEventArgs.ApplicationMessage.Topic, out string receivedRequestId, out int status, out long version)) { byte[] payloadBytes = receivedEventArgs.ApplicationMessage.Payload.ToArray() ?? Array.Empty(); @@ -1491,12 +1496,16 @@ private void RemoveOldOperations(object state) private async Task HandleIncomingEventMessageAsync(MqttApplicationMessageReceivedEventArgs receivedEventArgs) { + receivedEventArgs.AutoAcknowledge = true; + using var iotHubMessage = new Message(receivedEventArgs.ApplicationMessage.Payload.ToArray()); // The MqttTopic is in the format - devices/deviceId/modules/moduleId/inputs/inputName // We try to get the endpoint from the topic, if the topic is in the above format. string[] tokens = receivedEventArgs.ApplicationMessage.Topic.Split('/'); + PopulateMessagePropertiesFromMqttMessage(iotHubMessage, receivedEventArgs.ApplicationMessage); + // if there is an input name in the topic string, set the system property accordingly if (tokens.Length >= 6) {