From 0bf00dc13535178c21f7b1aa1af4704090dddf53 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 13:51:09 -0700 Subject: [PATCH 1/7] Add Version property to HistoryEvent class --- src/DurableSDK/HistoryEvent.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DurableSDK/HistoryEvent.cs b/src/DurableSDK/HistoryEvent.cs index ed16c4f9..9c3d79a7 100644 --- a/src/DurableSDK/HistoryEvent.cs +++ b/src/DurableSDK/HistoryEvent.cs @@ -50,6 +50,9 @@ internal class HistoryEvent [DataMember] public string Name { get; set; } + + [DataMember] + public string Version { get; set; } [DataMember] public string Result { get; set; } From d7dae33a8de5e42046092d637fe5f2b899a62137 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 15:04:56 -0700 Subject: [PATCH 2/7] Add Version property to OrchestrationContext class --- src/DurableSDK/OrchestrationContext.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/DurableSDK/OrchestrationContext.cs b/src/DurableSDK/OrchestrationContext.cs index 27f082db..19b1cdf3 100644 --- a/src/DurableSDK/OrchestrationContext.cs +++ b/src/DurableSDK/OrchestrationContext.cs @@ -36,5 +36,19 @@ public class OrchestrationContext internal OrchestrationActionCollector OrchestrationActionCollector { get; } = new OrchestrationActionCollector(); internal object CustomStatus { get; set; } + + public string Version + { + get + { + if (History == null) + { + return null; + } + + var executionStartedEvent = Array.Find(History, e => e.EventType == HistoryEventType.ExecutionStarted); + return executionStartedEvent?.Version; + } + } } } From 198a05a17c6019b4ea379e9a1be50fa48c473f29 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 17:43:46 -0700 Subject: [PATCH 3/7] Extract Version getter implementation to OrchestrationVersionExtractor --- src/DurableSDK/OrchestrationContext.cs | 8 +- .../OrchestrationVersionExtractor.cs | 31 +++++++ .../OrchestrationVersionExtractorTests.cs | 93 +++++++++++++++++++ 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 src/DurableSDK/OrchestrationVersionExtractor.cs create mode 100644 test/Unit/Durable/OrchestrationVersionExtractorTests.cs diff --git a/src/DurableSDK/OrchestrationContext.cs b/src/DurableSDK/OrchestrationContext.cs index 19b1cdf3..452dd30b 100644 --- a/src/DurableSDK/OrchestrationContext.cs +++ b/src/DurableSDK/OrchestrationContext.cs @@ -41,13 +41,7 @@ public string Version { get { - if (History == null) - { - return null; - } - - var executionStartedEvent = Array.Find(History, e => e.EventType == HistoryEventType.ExecutionStarted); - return executionStartedEvent?.Version; + return OrchestrationVersionExtractor.GetVersionFromHistory(History); } } } diff --git a/src/DurableSDK/OrchestrationVersionExtractor.cs b/src/DurableSDK/OrchestrationVersionExtractor.cs new file mode 100644 index 00000000..332dc4af --- /dev/null +++ b/src/DurableSDK/OrchestrationVersionExtractor.cs @@ -0,0 +1,31 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +namespace Microsoft.Azure.Functions.PowerShellWorker.Durable +{ + using System; + + /// + /// Helper class to extract version information from orchestration context. + /// + internal static class OrchestrationVersionExtractor + { + /// + /// Gets the orchestration version from a collection of history events. + /// + /// The history events to search. + /// The version, or null if not found. + public static string GetVersionFromHistory(HistoryEvent[] historyEvents) + { + if (historyEvents == null) + { + return null; + } + + var executionStartedEvent = Array.Find(historyEvents, e => e.EventType == HistoryEventType.ExecutionStarted); + return executionStartedEvent?.Version; + } + } +} diff --git a/test/Unit/Durable/OrchestrationVersionExtractorTests.cs b/test/Unit/Durable/OrchestrationVersionExtractorTests.cs new file mode 100644 index 00000000..61ba9dc8 --- /dev/null +++ b/test/Unit/Durable/OrchestrationVersionExtractorTests.cs @@ -0,0 +1,93 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +namespace Microsoft.Azure.Functions.PowerShellWorker.Test.Durable +{ + using System; + using Microsoft.Azure.Functions.PowerShellWorker.Durable; + using Xunit; + + public class OrchestrationVersionExtractorTests + { + [Fact] + public void GetVersionFromHistory_ReturnsNull_WhenHistoryIsNull() + { + // Act + string result = OrchestrationVersionExtractor.GetVersionFromHistory(null); + + // Assert + Assert.Null(result); + } + + [Fact] + public void GetVersionFromHistory_ReturnsNull_WhenHistoryHasNoExecutionStartedEvent() + { + // Arrange + var historyEvents = new[] + { + new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 1 }, + new HistoryEvent { EventType = HistoryEventType.TaskCompleted, EventId = 2, TaskScheduledId = 1 } + }; + + // Act + string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); + + // Assert + Assert.Null(result); + } + + [Fact] + public void GetVersionFromHistory_ReturnsVersion_WhenExecutionStartedEventExists() + { + // Arrange + const string expectedVersion = "1.0.0"; + var historyEvents = new[] + { + new HistoryEvent { + EventType = HistoryEventType.ExecutionStarted, + EventId = 1, + Version = expectedVersion + }, + new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 2 } + }; + + // Act + string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); + + // Assert + Assert.Equal(expectedVersion, result); + } + + [Fact] + public void GetVersionFromHistory_ReturnsFirstExecutionStartedVersion_WhenMultipleExecutionStartedEventsExist() + { + // Arrange + const string expectedVersion = "1.0.0"; + const string secondVersion = "2.0.0"; + + var historyEvents = new[] + { + new HistoryEvent { + EventType = HistoryEventType.ExecutionStarted, + EventId = 1, + Version = expectedVersion + }, + new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 2 }, + new HistoryEvent { + EventType = HistoryEventType.ExecutionStarted, + EventId = 3, + Version = secondVersion + } + }; + + // Act + string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); + + // Assert + Assert.Equal(expectedVersion, result); + Assert.NotEqual(secondVersion, result); + } + } +} From e9c13277ee2bbd3694dd57500af1df0fafed2c29 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 17:55:08 -0700 Subject: [PATCH 4/7] Clean up tests --- .../OrchestrationVersionExtractorTests.cs | 45 ++++--------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/test/Unit/Durable/OrchestrationVersionExtractorTests.cs b/test/Unit/Durable/OrchestrationVersionExtractorTests.cs index 61ba9dc8..8b3ca082 100644 --- a/test/Unit/Durable/OrchestrationVersionExtractorTests.cs +++ b/test/Unit/Durable/OrchestrationVersionExtractorTests.cs @@ -14,80 +14,51 @@ public class OrchestrationVersionExtractorTests [Fact] public void GetVersionFromHistory_ReturnsNull_WhenHistoryIsNull() { - // Act string result = OrchestrationVersionExtractor.GetVersionFromHistory(null); - // Assert Assert.Null(result); } [Fact] public void GetVersionFromHistory_ReturnsNull_WhenHistoryHasNoExecutionStartedEvent() { - // Arrange var historyEvents = new[] { - new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 1 }, - new HistoryEvent { EventType = HistoryEventType.TaskCompleted, EventId = 2, TaskScheduledId = 1 } + new HistoryEvent { EventType = HistoryEventType.OrchestratorStarted }, + new HistoryEvent { EventType = HistoryEventType.TaskScheduled } }; - // Act string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); - // Assert Assert.Null(result); } [Fact] public void GetVersionFromHistory_ReturnsVersion_WhenExecutionStartedEventExists() { - // Arrange - const string expectedVersion = "1.0.0"; var historyEvents = new[] { - new HistoryEvent { - EventType = HistoryEventType.ExecutionStarted, - EventId = 1, - Version = expectedVersion - }, - new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 2 } + new HistoryEvent { EventType = HistoryEventType.OrchestratorStarted }, + new HistoryEvent { EventType = HistoryEventType.ExecutionStarted, Version = "1.0" }, }; - // Act string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); - // Assert - Assert.Equal(expectedVersion, result); + Assert.Equal("1.0", result); } [Fact] public void GetVersionFromHistory_ReturnsFirstExecutionStartedVersion_WhenMultipleExecutionStartedEventsExist() { - // Arrange - const string expectedVersion = "1.0.0"; - const string secondVersion = "2.0.0"; - var historyEvents = new[] { - new HistoryEvent { - EventType = HistoryEventType.ExecutionStarted, - EventId = 1, - Version = expectedVersion - }, - new HistoryEvent { EventType = HistoryEventType.TaskScheduled, EventId = 2 }, - new HistoryEvent { - EventType = HistoryEventType.ExecutionStarted, - EventId = 3, - Version = secondVersion - } + new HistoryEvent { EventType = HistoryEventType.ExecutionStarted, Version = "1.0" }, + new HistoryEvent { EventType = HistoryEventType.ExecutionStarted, Version = "2.0" } }; - // Act string result = OrchestrationVersionExtractor.GetVersionFromHistory(historyEvents); - // Assert - Assert.Equal(expectedVersion, result); - Assert.NotEqual(secondVersion, result); + Assert.Equal("1.0", result); } } } From 816f494b6c69891d2ddf23380e41968aadb995cb Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 18:06:09 -0700 Subject: [PATCH 5/7] Optimize Version property in OrchestrationContext to use Lazy initialization for improved performance --- src/DurableSDK/OrchestrationContext.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/DurableSDK/OrchestrationContext.cs b/src/DurableSDK/OrchestrationContext.cs index 452dd30b..e8da2895 100644 --- a/src/DurableSDK/OrchestrationContext.cs +++ b/src/DurableSDK/OrchestrationContext.cs @@ -37,11 +37,18 @@ public class OrchestrationContext internal object CustomStatus { get; set; } + private readonly Lazy _version; + + public OrchestrationContext() + { + _version = new Lazy(() => OrchestrationVersionExtractor.GetVersionFromHistory(History)); + } + public string Version { get { - return OrchestrationVersionExtractor.GetVersionFromHistory(History); + return _version.Value; } } } From 65aa21770b07c9b2c9ed922da6dab0e7e82288d5 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Wed, 28 May 2025 18:14:09 -0700 Subject: [PATCH 6/7] Reorder --- src/DurableSDK/OrchestrationContext.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DurableSDK/OrchestrationContext.cs b/src/DurableSDK/OrchestrationContext.cs index e8da2895..130caf05 100644 --- a/src/DurableSDK/OrchestrationContext.cs +++ b/src/DurableSDK/OrchestrationContext.cs @@ -39,11 +39,6 @@ public class OrchestrationContext private readonly Lazy _version; - public OrchestrationContext() - { - _version = new Lazy(() => OrchestrationVersionExtractor.GetVersionFromHistory(History)); - } - public string Version { get @@ -51,5 +46,10 @@ public string Version return _version.Value; } } + + public OrchestrationContext() + { + _version = new Lazy(() => OrchestrationVersionExtractor.GetVersionFromHistory(History)); + } } } From 40ef4ff9fae476fba5be6866d00d42d1d594c0b6 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Thu, 29 May 2025 17:57:13 -0700 Subject: [PATCH 7/7] Update release notes --- release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release_notes.md b/release_notes.md index 16d551a7..079d2ccc 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1 +1 @@ -* Set environment variable to avoid Get-AzAccessToken breaking change \ No newline at end of file +* [Durable] Add Version property to $Context