Durable Orchestration¶
This recipe shows Java Durable Functions with an HTTP starter, orchestrator, and activity function using the Durable Task Java SDK.
Architecture¶
flowchart LR
CLIENT[Client] --> STARTER[HTTP starter]
STARTER --> ORCH[Orchestrator function]
ORCH --> ACT1[Activity: validate]
ORCH --> ACT2[Activity: process]
ORCH --> STATUS[Durable status endpoints] Prerequisites¶
Durable extension in host.json:
Maven dependencies:
<dependencies>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-java-library-durabletask</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
Java implementation¶
package com.contoso.functions;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.*;
import java.util.Optional;
public class DurableFunctions {
@FunctionName("orchestrationStarter")
public HttpResponseMessage orchestrationStarter(
@HttpTrigger(
name = "request",
methods = {HttpMethod.POST},
authLevel = AuthorizationLevel.FUNCTION,
route = "orchestrators/order"
) HttpRequestMessage<Optional<String>> request,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext
) {
DurableTaskClient client = durableContext.getClient();
String instanceId = client.scheduleNewOrchestrationInstance("orderOrchestrator", request.getBody().orElse("{}"));
return durableContext.createCheckStatusResponse(request, instanceId);
}
@FunctionName("orderOrchestrator")
public String orderOrchestrator(
@DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext context
) {
String payload = context.getInput(String.class);
String validated = context.callActivity("validateOrder", payload, String.class).await();
return context.callActivity("processOrder", validated, String.class).await();
}
@FunctionName("validateOrder")
public String validateOrder(
@DurableActivityTrigger(name = "payload") String payload
) {
return "validated:" + payload;
}
@FunctionName("processOrder")
public String processOrder(
@DurableActivityTrigger(name = "validatedPayload") String validatedPayload
) {
return "processed:" + validatedPayload;
}
}
Implementation notes¶
- Keep orchestrator code deterministic and move I/O to activity functions.
- Use
createCheckStatusResponseto return status query URLs to callers. - Design activities to be retry-safe because orchestration replays can occur.
- Keep payloads small and store large documents in Blob Storage.