Skip to content

Commit

Permalink
Add CreateCheckStatusResponseAsync APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
jviau committed Jan 10, 2024
1 parent 5d0219d commit 1016a60
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 11 deletions.
66 changes: 59 additions & 7 deletions src/Worker.Extensions.DurableTask/DurableTaskClientExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Serialization;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask.Client;
Expand All @@ -17,6 +18,52 @@ namespace Microsoft.Azure.Functions.Worker;
/// </summary>
public static class DurableTaskClientExtensions
{
/// <summary>
/// Creates an HTTP response that is useful for checking the status of the specified instance.
/// </summary>
/// <param name="client">The <see cref="DurableTaskClient"/>.</param>
/// <param name="request">The HTTP request that this response is for.</param>
/// <param name="instanceId">The ID of the orchestration instance to check.</param>
/// <param name="cancellation">The cancellation token.</param>
/// <returns>An HTTP 202 response with a Location header and a payload containing instance control URLs.</returns>
public static Task<HttpResponseData> CreateCheckStatusResponseAsync(
this DurableTaskClient client,
HttpRequestData request,
string instanceId,
CancellationToken cancellation = default)
{
return client.CreateCheckStatusResponseAsync(request, instanceId, HttpStatusCode.Accepted, cancellation);
}

/// <summary>
/// Creates an HTTP response that is useful for checking the status of the specified instance.
/// </summary>
/// <param name="client">The <see cref="DurableTaskClient"/>.</param>
/// <param name="request">The HTTP request that this response is for.</param>
/// <param name="instanceId">The ID of the orchestration instance to check.</param>
/// <param name="statusCode">The status code.</param>
/// <param name="cancellation">The cancellation token.</param>
/// <returns>An HTTP response with a Location header and a payload containing instance control URLs.</returns>
public static async Task<HttpResponseData> CreateCheckStatusResponseAsync(
this DurableTaskClient client,
HttpRequestData request,
string instanceId,
HttpStatusCode statusCode,
CancellationToken cancellation = default)
{
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}

HttpResponseData response = request.CreateResponse(statusCode);
object payload = SetHeadersAndGetPayload(client, request, response, instanceId);

ObjectSerializer serializer = GetObjectSerializer(response);
await serializer.SerializeAsync(response.Body, payload, payload.GetType(), cancellation);
return response;
}

/// <summary>
/// Creates an HTTP response that is useful for checking the status of the specified instance.
/// </summary>
Expand Down Expand Up @@ -55,6 +102,17 @@ public static HttpResponseData CreateCheckStatusResponse(
throw new ArgumentNullException(nameof(client));
}

HttpResponseData response = request.CreateResponse(statusCode);
object payload = SetHeadersAndGetPayload(client, request, response, instanceId);

ObjectSerializer serializer = GetObjectSerializer(response);
serializer.Serialize(response.Body, payload, payload.GetType(), cancellation);
return response;
}

private static object SetHeadersAndGetPayload(
DurableTaskClient client, HttpRequestData request, HttpResponseData response, string instanceId)
{
static string BuildUrl(string url, params string?[] queryValues)
{
bool appended = false;
Expand All @@ -79,23 +137,17 @@ static string BuildUrl(string url, params string?[] queryValues)
string formattedInstanceId = Uri.EscapeDataString(instanceId);
string instanceUrl = $"{baseUrl}/runtime/webhooks/durabletask/instances/{formattedInstanceId}";
string? commonQueryParameters = GetQueryParams(client);

HttpResponseData response = request.CreateResponse(statusCode);
response.Headers.Add("Location", BuildUrl(instanceUrl, commonQueryParameters));
response.Headers.Add("Content-Type", "application/json");

ObjectSerializer serializer = GetObjectSerializer(response);
var payload = new
return new
{
id = instanceId,
purgeHistoryDeleteUri = BuildUrl(instanceUrl, commonQueryParameters),
sendEventPostUri = BuildUrl($"{instanceUrl}/raiseEvent/{{eventName}}", commonQueryParameters),
statusQueryGetUri = BuildUrl(instanceUrl, commonQueryParameters),
terminatePostUri = BuildUrl($"{instanceUrl}/terminate", "reason={{text}}}", commonQueryParameters),
};

serializer.Serialize(response.Body, payload, payload.GetType(), cancellation);
return response;
}

private static ObjectSerializer GetObjectSerializer(HttpResponseData response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ public static Task<string> NoInputParameter(
}

[Function(ActivityName)]
public static string Activity([ActivityTrigger] MyInput input, FunctionContext executionContext)
public static string Activity([ActivityTrigger] string input, FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger(ActivityName);
logger.LogInformation("Received input {input}", input);
return $"{input.PropA}, {input.PropB}";
return input;
}

private static async Task<string> InputOrchestrationImpl(
TaskOrchestrationContext context, MyInput input, FunctionContext functionContext)
{
string result = await context.CallActivityAsync<string>(ActivityName, input) + ", ";
result += await context.CallActivityAsync<string>(ActivityName, new MyInput(functionContext.FunctionId, 1, true));
string result = await context.CallActivityAsync<string>(ActivityName) + ", ";
result += await context.CallActivityAsync<string>(ActivityName);
return result;
}

Expand Down

0 comments on commit 1016a60

Please sign in to comment.