Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Bug fix: Activity Functions can now use output bindings (https://github.com/Azure/azure-functions-powershell-worker/issues/646)
2 changes: 1 addition & 1 deletion src/RequestProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ private static TraceContext GetTraceContext(AzFunctionInfo functionInfo, Invocat
/// </summary>
private static void BindOutputFromResult(InvocationResponse response, AzFunctionInfo functionInfo, IDictionary results)
{
if (functionInfo.DurableFunctionInfo.Type == DurableFunctionType.None) // TODO: but let activity functions have output bindings, too
if (functionInfo.DurableFunctionInfo.Type != DurableFunctionType.OrchestrationFunction)
{
// Set out binding data and return response to be sent back to host
foreach (var (bindingName, bindingInfo) in functionInfo.OutputBindings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,56 @@ public async Task LegacyDurableCommandNamesStillWork()
}
}

[Fact]
public async Task ActivityCanHaveQueueBinding()
{
const string queueName = "outqueue";
await StorageHelpers.ClearQueue(queueName);
var initialResponse = await Utilities.GetHttpTriggerResponse("DurableClient", queryString: "?FunctionName=DurableOrchestratorWriteToQueue");
Assert.Equal(HttpStatusCode.Accepted, initialResponse.StatusCode);

var initialResponseBody = await initialResponse.Content.ReadAsStringAsync();
dynamic initialResponseBodyObject = JsonConvert.DeserializeObject(initialResponseBody);
var statusQueryGetUri = (string)initialResponseBodyObject.statusQueryGetUri;

var startTime = DateTime.UtcNow;

using var httpClient = new HttpClient();

while (true)
{
var statusResponse = await httpClient.GetAsync(statusQueryGetUri);
switch (statusResponse.StatusCode)
{
case HttpStatusCode.Accepted:
{
if (DateTime.UtcNow > startTime + _orchestrationCompletionTimeout)
{
Assert.True(false, $"The orchestration has not completed after {_orchestrationCompletionTimeout}");
}

await Task.Delay(TimeSpan.FromSeconds(2));
break;
}

case HttpStatusCode.OK:
{
var statusResponseBody = await GetResponseBodyAsync(statusResponse);
Assert.Equal("Completed", (string)statusResponseBody.runtimeStatus);

var queueMessage = await StorageHelpers.ReadFromQueue(queueName);
Assert.Equal("QueueData", queueMessage);
return;
}

default:
Assert.True(false, $"Unexpected orchestration status code: {statusResponse.StatusCode}");
break;
}
}
}


[Fact]
public async Task ActivityExceptionIsPropagatedThroughOrchestrator()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
},
{
"type": "queue",
"direction": "out",
"name": "outputQueueItem",
"queueName": "outqueue",
"connection": "AzureWebJobsStorage"
}
]
}
7 changes: 7 additions & 0 deletions test/E2E/TestFunctionApp/DurableActivityWritesToQueue/run.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
param($name)

Write-Information "Pushing to outputQueueItem output binding"
Push-OutputBinding -Name outputQueueItem -Value $name
Write-Information "Done"

"Hello $name!"
2 changes: 1 addition & 1 deletion test/E2E/TestFunctionApp/DurableClient/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Push-OutputBinding -Name Response -Value $Response

$Status = Get-DurableStatus -InstanceId $InstanceId
Write-Host "Orchestration $InstanceId status: $($Status | ConvertTo-Json)"
if ($Status.runtimeStatus -notin 'Pending', 'Running', 'Failed') {
if ($Status.runtimeStatus -notin 'Pending', 'Running', 'Failed', 'Completed') {
throw "Unexpected orchestration $InstanceId runtime status: $($Status.runtimeStatus)"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"bindings": [
{
"name": "Context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using namespace System.Net

param($Context)

Invoke-DurableActivity -FunctionName 'DurableActivityWritesToQueue' -Input 'QueueData'