Skip to content

Commit 3642ec0

Browse files
committed
# This is a combination of 37 commits.
# This is the 1st commit message: separate DF SDK classes from DF worker classes # This is the commit message #2: fix typo # This is the commit message #3: DurableSDK now compiles by itself # This is the commit message #4: Allow ExternalSDK to handle orchestration # This is the commit message #5: document next steps # This is the commit message #6: allow external SDK to set the user-code's input. Still need to refactor this logic for the worker to continue working with old SDK # This is the commit message #7: add import module # This is the commit message #8: supress traces # This is the commit message #9: avoid nullptr # This is the commit message #10: pass tests # This is the commit message #11: fix E2E tests # This is the commit message #12: develop E2E tests # This is the commit message #13: Enabled external durable client (#765) Co-authored-by: Michael Peng <[email protected]> # This is the commit message #14: bindings work # This is the commit message #15: conditional binding intialization # This is the commit message #16: conditional import # This is the commit message #17: Added exception handling logic # This is the commit message #18: Revert durableController name to durableFunctionsUtils # This is the commit message #19: Ensure unit tests are functioning properly # This is the commit message #20: Corrected unit test names # This is the commit message #21: Turned repeated variables in unit tests into static members # This is the commit message #22: Fixed issue with building the worker # This is the commit message #23: Fix E2E test # This is the commit message #24: Fixed unit test setup # This is the commit message #25: Fixed another unit test setup # This is the commit message #26: Remove string representation of booleans # This is the commit message #27: patch e2e test # This is the commit message #28: remove typo in toString # This is the commit message #29: Update PowerShell language worker pipelines (#750) * Install .Net to a global location * Remove .Net installation tasks * Update install .Net 6 task * Update Windows image to use windows-latest # This is the commit message #30: Make throughput warning message visible for tooling diagnosis (#757) # This is the commit message #31: Update grpc.tools to version 2.43.0 # This is the commit message #32: Update Google.Protobuf.Tools to version 3.19.4 # This is the commit message #33: Revert "Update Google.Protobuf.Tools to version 3.19.4" This reverts commit bcbd022. # This is the commit message #34: Revert "Update grpc.tools to version 2.43.0" This reverts commit ccb323a. # This is the commit message #35: Update Google.Protobuf to 3.19.4 and grpc.tools to 2.43.0 (#762) * Update grpc.tools to version 2.43.0 * Update Google.Protobuf.Tools to version 3.19.4 # This is the commit message #36: Switch from Grpc.Core to Grpc.Net.Client (#758) * Upgraded protobuf versions and removed Grpc.Core dependency * Updated channel and option types used * Change channel credentials * Added http prefix to url * Add valid URL check and explicitly include credentials # This is the commit message #37: Update pipeline logic to generate the SBOM for release builds (#767)
1 parent 67c81cc commit 3642ec0

File tree

66 files changed

+626
-327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+626
-327
lines changed

azure-pipelines-e2e-integration-tests.yml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,16 @@ strategy:
1111
linux:
1212
imageName: 'ubuntu-latest'
1313
windows:
14-
imageName: 'vs2017-win2016'
14+
imageName: 'windows-latest'
1515

1616
pool:
1717
vmImage: $(imageName)
1818

1919
steps:
2020
- pwsh: |
21-
Invoke-WebRequest 'https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1' -OutFile 'dotnet-install.ps1'
22-
./dotnet-install.ps1 -InstallDir "$env:ProgramFiles/dotnet" -Version "6.0.100" -Channel 'release'
23-
displayName: 'Install the .Net version used by the Core Tools for Windows'
24-
condition: eq( variables['Agent.OS'], 'Windows_NT' )
25-
26-
- bash: |
27-
curl -sSL https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh | bash /dev/stdin -v '6.0.100' -c 'release' --install-dir /usr/share/dotnet
28-
displayName: 'Install the .Net version used by the Core Tools for Linux'
29-
condition: eq( variables['Agent.OS'], 'Linux' )
21+
Import-Module "./tools/helper.psm1" -Force
22+
Install-Dotnet
23+
displayName: 'Install .NET 6.0'
3024

3125
- pwsh: ./test/E2E/Start-E2ETest.ps1 -UseCoreToolsBuildFromIntegrationTests
3226
env:

azure-pipelines.yml

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,14 @@ steps:
4343

4444
- pwsh: |
4545
$ErrorActionPreference = "Stop"
46-
if ($isReleaseBuild)
47-
{
48-
./build.ps1 -Clean -Configuration Release -BuildNumber "$(buildNumber)" -AddSBOM -SBOMUtilSASUrl $env:SBOMUtilSASUrl
49-
}
50-
else
51-
{
52-
./build.ps1 -Clean -Configuration Release -BuildNumber "$(buildNumber)"
53-
}
46+
$shouldAddSBOM = [bool]"$(IsReleaseBuild)"
47+
48+
./build.ps1 -Clean -Configuration Release -BuildNumber "$(buildNumber)" -AddSBOM:$shouldAddSBOM -SBOMUtilSASUrl "$(SBOMUtilSASUrl)"
5449
displayName: 'Build worker code'
55-
env:
56-
SBOMUtilSASUrl: $(SBOMUtilSASUrl)
5750

5851
- pwsh: ./build.ps1 -NoBuild -Test
5952
displayName: 'Running UnitTest'
6053

61-
- pwsh: |
62-
Invoke-WebRequest 'https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1' -OutFile 'dotnet-install.ps1'
63-
./dotnet-install.ps1 -InstallDir "$env:ProgramFiles/dotnet" -Version "6.0.100" -Channel 'release'
64-
displayName: 'Install the .Net version used by the Core Tools for Windows'
65-
condition: eq( variables['Agent.OS'], 'Windows_NT' )
66-
67-
- bash: |
68-
curl -sSL https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh | bash /dev/stdin -v '6.0.100' -c 'release' --install-dir /usr/share/dotnet
69-
displayName: 'Install the .Net version used by the Core Tools for Linux'
70-
condition: eq( variables['Agent.OS'], 'Linux' )
71-
7254
- pwsh: ./test/E2E/Start-E2ETest.ps1
7355
env:
7456
AzureWebJobsStorage: $(AzureWebJobsStorage)

src/Durable/PowerShellServices.cs

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/Durable/Commands/InvokeDurableActivityCommand.cs renamed to src/DurableSDK/Commands/InvokeDurableActivityCommand.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ protected override void EndProcessing()
4343
{
4444
var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
4545
var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey];
46-
var loadedFunctions = FunctionLoader.GetLoadedFunctions();
4746

4847
var task = new ActivityInvocationTask(FunctionName, Input, RetryOptions);
49-
ActivityInvocationTask.ValidateTask(task, loadedFunctions);
5048

5149
_durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
5250
task, context, NoWait.IsPresent,

src/Durable/Commands/SetFunctionInvocationContextCommand.cs renamed to src/DurableSDK/Commands/SetFunctionInvocationContextCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.Durable.Commands
99
{
1010
using System.Collections;
1111
using System.Management.Automation;
12+
using Microsoft.PowerShell.Commands;
1213

1314
/// <summary>
1415
/// Set the orchestration context.

src/Durable/DurableTaskHandler.cs renamed to src/DurableSDK/DurableTaskHandler.cs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
77
{
88
using System;
9+
using System.Collections;
910
using System.Collections.Generic;
11+
using System.Management.Automation;
1012
using System.Threading;
1113
using Microsoft.Azure.Functions.PowerShellWorker.Durable.Tasks;
12-
using Utility;
14+
using Microsoft.PowerShell.Commands;
1315

1416
internal class DurableTaskHandler
1517
{
@@ -47,6 +49,7 @@ public void StopAndInitiateDurableTaskOrReplay(
4749
}
4850

4951
completedHistoryEvent.IsProcessed = true;
52+
context.IsReplaying = completedHistoryEvent.IsPlayed;
5053

5154
switch (completedHistoryEvent.EventType)
5255
{
@@ -57,6 +60,13 @@ public void StopAndInitiateDurableTaskOrReplay(
5760
output(eventResult);
5861
}
5962
break;
63+
case HistoryEventType.EventRaised:
64+
var eventRaisedResult = GetEventResult(completedHistoryEvent);
65+
if (eventRaisedResult != null)
66+
{
67+
output(eventRaisedResult);
68+
}
69+
break;
6070

6171
case HistoryEventType.TaskFailed:
6272
if (retryOptions == null)
@@ -76,7 +86,7 @@ public void StopAndInitiateDurableTaskOrReplay(
7686
retryOptions.MaxNumberOfAttempts,
7787
onSuccess:
7888
result => {
79-
output(TypeExtensions.ConvertFromJson(result));
89+
output(ConvertFromJson(result));
8090
},
8191
onFailure);
8292

@@ -126,6 +136,7 @@ public void WaitAll(
126136
var allTasksCompleted = completedEvents.Count == tasksToWaitFor.Count;
127137
if (allTasksCompleted)
128138
{
139+
context.IsReplaying = completedEvents.Count == 0 ? false : completedEvents[0].IsPlayed;
129140
CurrentUtcDateTimeUpdater.UpdateCurrentUtcDateTime(context);
130141

131142
foreach (var completedHistoryEvent in completedEvents)
@@ -185,6 +196,7 @@ public void WaitAny(
185196
var anyTaskCompleted = completedTasks.Count > 0;
186197
if (anyTaskCompleted)
187198
{
199+
context.IsReplaying = context.History[firstCompletedHistoryEventIndex].IsPlayed;
188200
CurrentUtcDateTimeUpdater.UpdateCurrentUtcDateTime(context);
189201
// Return a reference to the first completed task
190202
output(firstCompletedTask);
@@ -206,15 +218,41 @@ private static object GetEventResult(HistoryEvent historyEvent)
206218

207219
if (historyEvent.EventType == HistoryEventType.TaskCompleted)
208220
{
209-
return TypeExtensions.ConvertFromJson(historyEvent.Result);
221+
return ConvertFromJson(historyEvent.Result);
210222
}
211223
else if (historyEvent.EventType == HistoryEventType.EventRaised)
212224
{
213-
return TypeExtensions.ConvertFromJson(historyEvent.Input);
225+
return ConvertFromJson(historyEvent.Input);
214226
}
215227
return null;
216228
}
217229

230+
public static object ConvertFromJson(string json)
231+
{
232+
object retObj = JsonObject.ConvertFromJson(json, returnHashtable: true, error: out _);
233+
234+
if (retObj is PSObject psObj)
235+
{
236+
retObj = psObj.BaseObject;
237+
}
238+
239+
if (retObj is Hashtable hashtable)
240+
{
241+
try
242+
{
243+
// ConvertFromJson returns case-sensitive Hashtable by design -- JSON may contain keys that only differ in case.
244+
// We try casting the Hashtable to a case-insensitive one, but if that fails, we keep using the original one.
245+
retObj = new Hashtable(hashtable, StringComparer.OrdinalIgnoreCase);
246+
}
247+
catch
248+
{
249+
retObj = hashtable;
250+
}
251+
}
252+
253+
return retObj;
254+
}
255+
218256
private void InitiateAndWaitForStop(OrchestrationContext context)
219257
{
220258
context.OrchestrationActionCollector.Stop();
File renamed without changes.
File renamed without changes.

src/Durable/IOrchestrationInvoker.cs renamed to src/DurableSDK/IOrchestrationInvoker.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
77
{
8+
using System;
89
using System.Collections;
10+
using System.Management.Automation;
911

1012
internal interface IOrchestrationInvoker
1113
{
1214
Hashtable Invoke(OrchestrationBindingInfo orchestrationBindingInfo, IPowerShellServices pwsh);
15+
void SetExternalInvoker(Action<PowerShell> externalInvoker);
1316
}
1417
}

src/Durable/IPowerShellServices.cs renamed to src/DurableSDK/IPowerShellServices.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@
55

66
namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
77
{
8+
using Microsoft.Azure.WebJobs.Script.Grpc.Messages;
89
using System;
910
using System.Management.Automation;
1011

1112
internal interface IPowerShellServices
1213
{
14+
PowerShell GetPowerShell();
15+
16+
bool UseExternalDurableSDK();
17+
1318
void SetDurableClient(object durableClient);
1419

15-
void SetOrchestrationContext(OrchestrationContext orchestrationContext);
20+
OrchestrationBindingInfo SetOrchestrationContext(ParameterBinding orchestrationContext, out Action<object> externalInvoker);
1621

1722
void ClearOrchestrationContext();
1823

24+
public void TracePipelineObject();
25+
public void AddParameter(string name, object value);
26+
27+
1928
IAsyncResult BeginInvoke(PSDataCollection<object> output);
2029

2130
void EndInvoke(IAsyncResult asyncResult);

src/Durable/OrchestrationActionCollector.cs renamed to src/DurableSDK/OrchestrationActionCollector.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.Durable
1111
using System.Threading;
1212

1313
using Microsoft.Azure.Functions.PowerShellWorker.Durable.Actions;
14+
using Newtonsoft.Json;
1415

1516
internal class OrchestrationActionCollector
1617
{

src/Durable/OrchestrationContext.cs renamed to src/DurableSDK/OrchestrationContext.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ public class OrchestrationContext
2020
public object Input { get; internal set; }
2121

2222
[DataMember]
23-
internal string InstanceId { get; set; }
23+
public string InstanceId { get; set; }
2424

2525
[DataMember]
2626
internal string ParentInstanceId { get; set; }
2727

2828
[DataMember]
29-
internal bool IsReplaying { get; set; }
29+
public bool IsReplaying { get; set; }
3030

3131
[DataMember]
3232
internal HistoryEvent[] History { get; set; }
@@ -35,6 +35,15 @@ public class OrchestrationContext
3535

3636
internal OrchestrationActionCollector OrchestrationActionCollector { get; } = new OrchestrationActionCollector();
3737

38+
internal object ExternalResult;
39+
internal bool ExternalIsError;
40+
41+
internal void SetExternalResult(object result, bool isError)
42+
{
43+
this.ExternalResult = result;
44+
this.ExternalIsError = isError;
45+
}
46+
3847
internal object CustomStatus { get; set; }
3948
}
4049
}

0 commit comments

Comments
 (0)