Creare la prima funzione durevole in Java

Durable Functions è un'estensione di Funzioni di Azure che consente di scrivere funzioni con stato in un ambiente senza server. L'estensione gestisce automaticamente lo stato, i checkpoint e i riavvii.

In questa guida introduttiva si apprenderà come creare e testare un'app Durable Functions "Hello World" in Java. L'app Durable Functions più di base contiene le tre funzioni seguenti:

  • Funzione dell'agente di orchestrazione: descrive un flusso di lavoro che orchestra le altre funzioni.
  • Funzione dell'attività: chiamata dalla funzione dell'agente di orchestrazione, 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.

Questa guida introduttiva illustra come creare questa app "Hello World", che è possibile eseguire in modi diversi. Usare il selettore precedente per scegliere l'approccio preferito.

Prerequisiti

Per completare questa esercitazione è necessario:

  • Java Developer Kit, versione 8 o successiva.

  • Apache Maven versione 3.0 o successiva.

  • Versione più recente di Funzioni di Azure Core Tools.

    • Per Funzioni di Azure 4.x, è necessario Core Tools v4.0.4915 o versione successiva.
  • Un account Archiviazione di Azure, che richiede una sottoscrizione 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 quanto segue a 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 host.json file alla directory del progetto. La voce deve essere simile alla 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 di estensione v4 Funzioni di Azure ha attualmente il supporto necessario per Durable Functions per Java. Durable Functions per Java non è supportato nei bundle di estensioni v3 e early. 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 local.settings.json file alla directory del progetto per configurare il provider di archiviazione. Per usare Archiviazione di Azure come provider, impostare il valore di AzureWebJobsStorage sul stringa di connessione dell'account Archiviazione di Azure:

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

Creare le funzioni

Il codice di esempio seguente mostra un semplice esempio di ognuno di essi:

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 gets 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 con il comando Maven

  1. Eseguire il comando seguente per generare un progetto con 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
  1. Seguire le istruzioni e fornire le informazioni seguenti:
Richiesta Valore
groupId com.function
artifactId myDurableFunction
version 1.0-SNAPSHOT
package com.function
Y Premere INVIO per confermare

Ora è disponibile un progetto locale generato con le tre funzioni necessarie per un'app Durable Functions di base.

Verificare di avere com.microsoft:durabletask-azure-functions come dipendenza in pom.xml.

Configurare il provider di archiviazione back-end

Durable Functions richiede un provider di archiviazione per archiviare lo stato di runtime. È possibile configurare per usare Archiviazione di Azure come provider di archiviazione in local.settings.json specificando il stringa di connessione dell'account Archiviazione di Azure come valore di AzureWebJobsStorage:

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

Creare il progetto locale

  1. In Visual Studio Code premere F1 (o CTRL/CMD+MAIUSC+P) per aprire il riquadro comandi. Nel riquadro comandi cercare e selezionare Azure Functions: Create New Project....

    Screenshot of create new functions project.

  2. Scegliere una cartella vuota come posizione del progetto e quindi Seleziona.

  3. Seguire le istruzioni e fornire le informazioni seguenti:

    Richiesta Valore
    Selezionare una lingua Scegliere Java.
    Selezionare una versione di Java Scegliere Java 8 o versione successiva, la versione Java in cui vengono eseguite le funzioni in Azure. Scegliere una versione di Java che è stata verificata in locale.
    Specificare un ID gruppo com.function.
    Specificare un ID artefatto myDurableFunction.
    Specificare una versione 1.0-SNAPSHOT.
    Specificare un nome di pacchetto com.function.
    Specificare un nome dell'app myDurableFunction.
    Selezionare lo strumento di compilazione per il progetto Java Scegliere Maven.
    Selezionare la modalità di apertura del progetto Scegliere Open in new window.

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

Aggiungere funzioni al progetto

  1. Nel riquadro comandi cercare e selezionare Azure Functions: Create Function....

  2. Selezionare Change template filter .All

  3. Seguire le istruzioni e fornire le informazioni seguenti:

    Richiesta Valore
    Selezionare un modello per la funzione DurableFunctionsOrchestration
    Specificare un nome di pacchetto com.function
    Specificare un nome di funzione DurableFunctionsOrchestrator
  4. Scegliere Select storage account nella finestra popup in cui viene chiesto di configurare le informazioni sull'account di archiviazione e seguire le istruzioni.

È ora necessario avere le tre funzioni di base per un'app Durable Functions generata.

Configurare pom.xml e host.json

Aggiungere la dipendenza seguente a pom.xml:

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

Aggiungere la extensions proprietà a host.json:

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

Testare la funzione in locale

Azure Functions Core Tools consente di eseguire un progetto Funzioni di Azure nel computer di sviluppo locale.

Nota

Durable Functions per Java richiede Funzioni di Azure Core Tools v4.0.4915 o versione successiva. È possibile vedere quale versione è installata eseguendo il func --version comando dal 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 Terminale copiare l'endpoint dell'URL della funzione attivata da HTTP.

    Screenshot of Azure local output.

  3. Con uno strumento come Postman o cURL, inviare una richiesta HTTP POST all'endpoint URL. Si dovrebbe ottenere una risposta simile alla seguente:

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

    La risposta è il risultato iniziale della funzione HTTP che informa che l'orchestrazione durevole è stata avviata correttamente. Non è ancora il risultato finale dell'orchestrazione. La risposta include alcuni URL utili. Per il momento si eseguirà 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, è anche possibile continuare a usare Postman o cURL per inviare la richiesta GET.

    La richiesta eseguirà una query per determinare lo stato dell'istanza di orchestrazione. Si otterrà una risposta conclusiva in cui si specifica che l'istanza è stata completata e contenente l'output o i risultati della funzione durevole. L'aspetto sarà simile al seguente:

    {
        "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"
    }