Avvio rapido: Creare un'app Java Durable Functions

Usare Durable Functions, una funzionalità di Funzioni di Azure, per scrivere flussi di lavoro serverless con stato in Java. In questa guida introduttiva si clona ed esegue un'app di esempio che illustra due modelli di orchestrazione comuni:

  • Concatenamento delle funzioni: chiama le attività in sequenza (Tokyo → Seattle → Londra).
  • Fan-out/fan-in: chiama le attività in parallelo tra cinque città, quindi aggrega i risultati.

Alla fine, avrai entrambe le orchestrazioni in esecuzione in locale con l'emulatore Durable Task Scheduler e potrai visualizzarne lo stato nella dashboard.

  • Clonare e preparare il progetto di esempio Hello Cities.
  • Configurare l'emulatore Durable Task Scheduler e Azurite per lo sviluppo locale.
  • Compilare ed eseguire l'app per le funzioni e attivare entrambe le orchestrazioni.
  • Esamina lo stato dell'orchestrazione e il relativo output nel dashboard di Durable Task Scheduler.

Prerequisiti

Configurare l'emulatore dell'utilità di pianificazione di Durable Task

L'emulatore Durable Task Scheduler fornisce un ambiente di sviluppo locale che consente di testare le orchestrazioni senza un abbonamento di Azure. L'host Java Functions richiede anche Azurite per l'archiviazione locale.

Avviare entrambi i contenitori:

docker run -d --name dtsemulator -p 8080:8080 -p 8082:8082 \
  mcr.microsoft.com/dts/dts-emulator:latest

docker run -d --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 \
  mcr.microsoft.com/azure-storage/azurite

Suggerimento

Una volta avviato l'emulatore, è possibile accedere al dashboard di Durable Task Scheduler all'indirizzo http://localhost:8082 per monitorare le orchestrazioni.

Eseguire l'esempio di avvio rapido

  1. Vai alla directory di esempio di Hello Cities:

    cd samples/durable-functions/java/HelloCities
    
  2. Verificare che il local.settings.json file contenga la configurazione seguente:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "java",
        "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
      }
    }
    
  3. Compilare il progetto:

    mvn clean package
    
  4. Avviare l'app per le funzioni:

    mvn azure-functions:run
    
  5. In un terminale separato, avvia l'orchestrazione del concatenamento di funzioni:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartChaining
    $response
    

    La risposta contiene gli URL di stato per l'istanza di orchestrazione. Copiare il statusQueryGetUri valore ed eseguirlo per controllare il risultato:

    Invoke-RestMethod -Uri $response.statusQueryGetUri
    
  6. Attiva l'orchestrazione fan-out/fan-in:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartFanOutFanIn
    Invoke-RestMethod -Uri $response.statusQueryGetUri
    

Output previsto

La richiesta POST restituisce una risposta JSON con URL di stato. Per esempio:

{
  "id": "<instanceId>",
  "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/<instanceId>?code=...",
  "sendEventPostUri": "...",
  "terminatePostUri": "...",
  "purgeHistoryDeleteUri": "..."
}

Quando si interroga statusQueryGetUri e l'runtimeStatus dell'orchestrazione è Completed, è possibile trovare i risultati del saluto nel campo output. L'orchestrazione del concatenamento restituisce:

{
  "name": "ChainingOrchestration",
  "runtimeStatus": "Completed",
  "output": "Hello Tokyo! Hello Seattle! Hello London!"
}

L'orchestrazione fan-out/fan-in restituisce:

{
  "name": "FanOutFanInOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!", "Hello Paris!", "Hello Berlin!"]
}

Suggerimento

Se runtimeStatus mostra Running o Pending, attendere un attimo ed eseguire di nuovo una statusQueryGetUri query.

Apri il dashboard di Durable Task Scheduler all'indirizzo http://localhost:8082 per visualizzare lo stato dell'orchestrazione e la cronologia di esecuzione.

Informazioni sul codice

Il progetto di esempio in src/main/java/com/example/Functions.java contiene tutti e tre i tipi di funzione necessari per un'app Durable Functions.

Funzione dell'attività

L'attività SayHello prende il nome di una città e restituisce un saluto:

@FunctionName("SayHello")
public String sayHello(
        @DurableActivityTrigger(name = "city") String city) {
    return "Hello " + city + "!";
}

Funzioni dell'agente di orchestrazione

L'orchestratore della concatenazione chiama SayHello in sequenza per tre città:

@FunctionName("ChainingOrchestration")
public String chainingOrchestration(
        @DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {

    String result = "";
    result += ctx.callActivity("SayHello", "Tokyo", String.class).await();
    result += " " + ctx.callActivity("SayHello", "Seattle", String.class).await();
    result += " " + ctx.callActivity("SayHello", "London", String.class).await();
    return result;
}

L'orchestratore fan-out/fan-in pianifica le attività in parallelo:

@FunctionName("FanOutFanInOrchestration")
public List<String> fanOutFanInOrchestration(
        @DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {

    String[] cities = {"Tokyo", "Seattle", "London", "Paris", "Berlin"};
    List<Task<String>> parallelTasks = new ArrayList<>();

    for (String city : cities) {
        parallelTasks.add(ctx.callActivity("SayHello", city, String.class));
    }

    List<String> results = new ArrayList<>();
    for (Task<String> task : parallelTasks) {
        results.add(task.await());
    }

    return results;
}

Funzioni del client

Le funzioni client attivate da HTTP avviano ogni orchestrazione:

@FunctionName("StartChaining")
public HttpResponseMessage startChaining(
        @HttpTrigger(name = "req", methods = {HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Void> request,
        @DurableClientInput(name = "durableContext") DurableClientContext durableContext) {

    DurableTaskClient client = durableContext.getClient();
    String instanceId = client.scheduleNewOrchestrationInstance("ChainingOrchestration");
    return durableContext.createCheckStatusResponse(request, instanceId);
}

Configurazione

L'esempio usa l'emulatore di Durable Task Scheduler come backend di archiviazione. Questa operazione è configurata in host.json:

{
  "extensions": {
    "durableTask": {
      "hubName": "default",
      "storageProvider": {
        "type": "azureManaged",
        "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
      }
    }
  }
}

La stringa di connessione dell'emulatore è impostata in local.settings.json:

{
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
  }
}

Pulire le risorse

Quando avete finito, fermate i contenitori dell'emulatore:

docker stop dtsemulator azurite && docker rm dtsemulator azurite

Passaggi successivi