Avvio rapido: Creare un'app Java Durable Functions

Usare Durable Functions, un'estensione di Funzioni di Azure per scrivere funzioni con stato in un ambiente serverless. Durable Functions gestisce lo stato, i checkpoint e i riavvii nell'applicazione.

In questo avvio rapido si crea e si testa un'app Durable Functions "hello world" in Java.

L'app Durable Functions più semplice ha tre funzioni:

  • Funzione dell'agente di orchestrazione: un flusso di lavoro che orchestra le altre funzioni.
  • Funzione dell'attività: una funzione chiamata dalla funzione dell'agente di orchestrazione, che esegue le operazioni e restituisce facoltativamente un valore.
  • Funzione client: normale funzione di Azure che avvia una funzione dell'agente di orchestrazione. Questo esempio usa una funzione attivata tramite HTTP.

Questo avvio rapido descrive differenti modi per creare questa app "hello world". Usare il selettore nella parte superiore della pagina per impostare l'approccio preferito.

Prerequisiti

Per completare l'esercitazione introduttiva, sono necessari gli elementi seguenti:

  • Java Developer Kit versione 8 o successiva installata.

  • Apache Maven, versione 3.0 o successiva installata.

  • La versione più recente di Azure Functions Core Tools.

    Per Funzioni di Azure 4.x, è necessario Core Tools versione 4.0.4915 o successiva.

  • Strumento di test HTTP che protegge i dati. Per altre informazioni, vedere Strumenti di test HTTP.

  • Una sottoscrizione di Azure. Per usare Durable Functions, è necessario un account di archiviazione di Azure.

Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.

Aggiungere le dipendenze e i plug-in necessari al progetto

Aggiungere il codice seguente al file pom.xml:

<properties>
  <azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
  <azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
  <durabletask.azure.functions>1.0.0</durabletask.azure.functions>
  <functionAppName>your-unique-app-name</functionAppName>
</properties>

<dependencies>
  <dependency>
    <groupId>com.microsoft.azure.functions</groupId>
    <artifactId>azure-functions-java-library</artifactId>
    <version>${azure.functions.java.library.version}</version>
  </dependency>
  <dependency>
    <groupId>com.microsoft</groupId>
    <artifactId>durabletask-azure-functions</artifactId>
    <version>${durabletask.azure.functions}</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
    </plugin>
    <plugin>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-functions-maven-plugin</artifactId>
      <version>${azure.functions.maven.plugin.version}</version>
      <configuration>
        <appName>${functionAppName}</appName>
        <resourceGroup>java-functions-group</resourceGroup>
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <region>westus</region>
        <runtime>
          <os>windows</os>
          <javaVersion>11</javaVersion>
        </runtime>
        <appSettings>
          <property>
            <name>FUNCTIONS_EXTENSION_VERSION</name>
            <value>~4</value>
          </property>
        </appSettings>
      </configuration>
      <executions>
        <execution>
          <id>package-functions</id>
          <goals>
            <goal>package</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
    </plugin>
  </plugins>
</build>

Aggiungere i file JSON necessari

Aggiungere un file host.json alla directory del progetto. Dovrebbe risultare simile all'esempio seguente:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Nota

È importante notare che solo il bundle dell'estensione Funzioni di Azure v4 ha attualmente il supporto necessario per Durable Functions per Java. Durable Functions per Java non è supportato nei bundle di estensioni v3 e precedenti. Per altre informazioni sui bundle di estensioni, vedere la documentazione relativa ai bundle di estensioni.

Durable Functions richiede un provider di archiviazione per archiviare lo stato di runtime. Aggiungere un file local.settings.json alla directory del progetto per configurare il provider di archiviazione. Per usare Archiviazione di Azure come provider, impostare il valore di AzureWebJobsStorage sulla stringa di connessione dell'account di Archiviazione di Azure:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Creare le funzioni

Il codice di esempio seguente illustra un esempio di base di ogni tipo di funzione:

import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import java.util.*;

import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.DurableActivityTrigger;
import com.microsoft.durabletask.azurefunctions.DurableClientContext;
import com.microsoft.durabletask.azurefunctions.DurableClientInput;
import com.microsoft.durabletask.azurefunctions.DurableOrchestrationTrigger;

public class DurableFunctionsSample {
    /**
     * This HTTP-triggered function starts the orchestration.
     */
    @FunctionName("StartOrchestration")
    public HttpResponseMessage startOrchestration(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @DurableClientInput(name = "durableContext") DurableClientContext durableContext,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("Cities");
        context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
        return durableContext.createCheckStatusResponse(request, instanceId);
    }

    /**
     * This is the orchestrator function, which can schedule activity functions, create durable timers,
     * or wait for external events in a way that's completely fault-tolerant.
     */
    @FunctionName("Cities")
    public String citiesOrchestrator(
            @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {
        String result = "";
        result += ctx.callActivity("Capitalize", "Tokyo", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "London", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Seattle", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Austin", String.class).await();
        return result;
    }

    /**
     * This is the activity function that is invoked by the orchestrator function.
     */
    @FunctionName("Capitalize")
    public String capitalize(@DurableActivityTrigger(name = "name") String name, final ExecutionContext context) {
        context.getLogger().info("Capitalizing: " + name);
        return name.toUpperCase();
    }
}

Creare un progetto locale usando il comando Maven

Eseguire il comando seguente per generare un progetto contenente le funzioni di base di un'app Durable Functions:

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.51 -Dtrigger=durablefunctions

Quando richiesto, immettere le informazioni seguenti:

Richiesta Azione
groupId Immettere com.function.
artifactId Immettere myDurableFunction.
version Selezionare 1.0-SNAPSHOT.
package Immettere com.function.
Y Immettere Y e selezionare Invio per confermare.

È ora disponibile un progetto locale con le tre funzioni incluse in un'app Durable Functions di base.

Verificare che com.microsoft:durabletask-azure-functions sia impostato come dipendenza nel file pom.xml.

Configurare il provider di archiviazione back-end

Durable Functions richiede un provider di archiviazione per archiviare lo stato di runtime. È possibile impostare Archiviazione di Azure come provider di archiviazione in local.settings.json. Usare la stringa di connessione dell'account di archiviazione di Azure come valore per AzureWebJobsStorage come nell'esempio seguente:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

Creare il progetto locale

  1. In Visual Studio Code, selezionare F1 (o Ctrl/Cmd+Maiuscolo+P) per aprire il riquadro comandi. Quando richieste (>), immettere e selezionare Funzioni di Azure: Crea nuovo progetto.

    Screenshot del comando crea nuovo progetto di funzioni.

  2. Selezionare Sfoglia. Nella finestra di dialogo Seleziona cartella andare a una cartella da usare per il progetto, quindi scegliere Seleziona.

  3. Quando richiesto, immettere le informazioni seguenti:

    Richiesta Azione
    Selezionare una lingua Selezionare Java.
    Selezionare una versione di Java Selezionare Java 8 o versione successiva. Selezionare la versione Java in cui vengono eseguite le funzioni in Azure e una verificata in locale.
    Specificare un ID gruppo Immettere com.function.
    Specificare un ID artefatto Immettere myDurableFunction.
    Specificare una versione Immettere 1.0-SNAPSHOT.
    Specificare un nome di pacchetto Immettere com.function.
    Specificare un nome di app Immettere myDurableFunction.
    Selezionare lo strumento di compilazione per il progetto Java Selezionare Maven.
    Selezionare come si vuole aprire il progetto Selezionare Apri in nuova finestra.

È ora disponibile un progetto con una funzione HTTP di esempio. È possibile rimuovere questa funzione se si desidera, perché si aggiungono le funzioni di base di un'app Durable Functions nel passaggio successivo.

Aggiungere funzioni al progetto

  1. Nel riquadro comandi immettere e selezionare Funzioni di Azure: Crea funzione.

  2. Per Modifica filtro modello, selezionare Tutti.

  3. Quando richiesto, immettere le informazioni seguenti:

    Richiesta Azione
    Selezionare un modello per la funzione Selezionare DurableFunctionsOrchestration.
    Specificare un nome di pacchetto Immettere com.function.
    Specificare un nome di funzione Immettere DurableFunctionsOrchestrator.
  4. Nella finestra di dialogo scegliere Selezionare l'account di archiviazione per configurare un account di archiviazione quindi seguire le istruzioni.

Ora dovrebbero essere presenti le tre funzioni di base generate per un'app Durable Functions.

Configurare pom.xml e host.json

Aggiungere la dipendenza seguente al file pom.xml:

<dependency>
  <groupId>com.microsoft</groupId>
  <artifactId>durabletask-azure-functions</artifactId>
  <version>1.0.0</version>
</dependency>

Aggiungere la proprietà extensions al file host.json:

"extensions": { "durableTask": { "hubName": "JavaTestHub" }}

Testare la funzione in locale

Azure Functions Core Tools offre la possibilità di eseguire un progetto Funzioni di Azure nel computer di sviluppo locale.

Nota

Durable Functions per Java richiede Azure Functions Core Tools versione 4.0.4915 o successiva. È possibile visualizzare la versione installata eseguendo il comando func --version nel terminale.

  1. Se si usa Visual Studio Code, aprire una nuova finestra del terminale ed eseguire i comandi seguenti per compilare il progetto:

    mvn clean package
    

    Eseguire quindi la funzione durevole:

    mvn azure-functions:run
    
  2. Nel pannello del terminale copiare l'endpoint dell'URL della funzione attivata da HTTP.

    Screenshot dell'output locale di Azure.

  3. Usare uno strumento di test HTTP per inviare una richiesta HTTP POST all'endpoint URL.

    La risposta dovrebbe essere simile all'esempio seguente:

    {
        "id": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/raiseEvent/{eventName}?code=ACCupah_QfGKo...",
        "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/terminate?reason={text}&code=ACCupah_QfGKo..."
    }
    

    La risposta è il risultato iniziale della funzione HTTP. Informa che l'orchestrazione durevole è stata avviata correttamente. Non visualizza ancora il risultato finale dell'orchestrazione. La risposta include alcuni URL utili. Per il momento eseguire una query relativa allo stato dell'orchestrazione.

  4. Copiare il valore dell'URL per statusQueryGetUri, incollarlo nella barra degli indirizzi del browser ed eseguire la richiesta. In alternativa, è possibile continuare a usare lo strumento di test HTTP per inviare la richiesta GET.

    La richiesta esegue una query per determinare lo stato dell'istanza di orchestrazione. Si noterà che l'istanza è stata completata e che include gli output o i risultati della funzione durevole, come in questo esempio:

    {
        "name": "Cities",
        "instanceId": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": "",
        "output":"TOKYO, LONDON, SEATTLE, AUSTIN",
        "createdTime": "2022-12-12T05:00:02Z",
        "lastUpdatedTime": "2022-12-12T05:00:06Z"
    }