Erstellen Ihrer ersten dauerhaften Funktion in Java

Durable Functions ist eine Erweiterung von Azure Functions, mit der Sie zustandsbehaftete Funktionen in einer serverlosen Umgebung schreiben können. Die Erweiterung verwaltet Status, Prüfpunkte und Neustarts für Sie.

In dieser Schnellstartanleitung erfahren Sie, wie Sie eine „Hallo Welt“-Durable Functions-App in Java erstellen und testen. Die einfachste Durable Functions-App enthält die folgenden drei Funktionen:

  • Orchestratorfunktion: Beschreibt einen Workflow, der andere Funktionen orchestriert.
  • Aktivitätsfunktion: Wird von der Orchestratorfunktion aufgerufen, führt die Aufgabe aus und gibt optional einen Wert zurück.
  • Clientfunktion: Eine reguläre Azure-Funktion, die eine Orchestratorfunktion startet. In diesem Beispiel wird eine per HTTP ausgelöste Funktion verwendet.

In dieser Schnellstartanleitung erfahren Sie, wie Sie diese „Hallo Welt“-App erstellen, was auf unterschiedliche Weise möglich ist. Verwenden Sie den Selektor oben, um Ihre bevorzugte Vorgehensweise auszuwählen.

Voraussetzungen

Für dieses Tutorial benötigen Sie Folgendes:

  • Java Developer Kit, Version 8 oder höher

  • Apache Maven, Version 3.0 oder höher

  • Die neueste Version der Azure Functions Core Tools.

    • Für Azure Functions 4.x ist Core Tools v4.0.4915 oder höher erforderlich.
  • Ein Azure Storage-Konto, das erfordert, dass Sie über ein Azure-Abonnement verfügen.

Sollten Sie über kein Azure-Abonnement verfügen, können Sie zunächst ein kostenloses Azure-Konto erstellen.

Hinzufügen erforderlicher Abhängigkeiten und Plug-Ins zu Ihrem Projekt

Fügen Sie Ihrem pom.xml-Code Folgendes hinzu:

<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>

Hinzufügen erforderlicher JSON-Dateien

Fügen Sie Ihrem Projektverzeichnis eine host.json-Datei hinzu. Es sollte ungefähr wie folgt aussehen:

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

Hinweis

Beachten Sie unbedingt, dass derzeit nur das Erweiterungspaket von Azure Functions v4 die erforderliche Unterstützung für Durable Functions für Java bietet. Durable Functions für Java wird in v3- und frühen Erweiterungspaketen nicht unterstützt. Weitere Informationen zu Erweiterungspaketen finden Sie in der Dokumentation zu Erweiterungspaketen.

Durable Functions benötigt einen Speicheranbieter, um den Laufzeitzustand zu speichern. Fügen Sie Ihrem Projektverzeichnis eine local.settings.json-Datei hinzu, um den Speicheranbieter zu konfigurieren. Zum Verwenden von Azure Storage als Anbieter legen Sie den Wert von AzureWebJobsStorage auf die Verbindungszeichenfolge Ihres Azure Storage-Kontos fest:

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

Erstellen Ihrer Funktionen

Der folgende Beispielcode zeigt jeweils ein einfaches Beispiel:

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();
    }
}

Erstellen eines lokalen Projekts mit einem Maven-Befehl

  1. Führen Sie den folgenden Befehl aus, um ein Projekt mit den grundlegenden Funktionen einer Durable Functions-App zu generieren:
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.51 -Dtrigger=durablefunctions
  1. Geben Sie an den Eingabeaufforderungen die folgenden Informationen an:
Prompt Wert
groupId com.function
artifactId myDurableFunction
version 1.0-SNAPSHOT
package com.function
J Drücken Sie die EINGABETASTE zur Bestätigung

Jetzt haben Sie ein lokales Projekt mit den drei Funktionen generiert, die für eine einfache Durable Functions-App erforderlich sind.

Vergewissern Sie sich, dass com.microsoft:durabletask-azure-functions als Abhängigkeit in Ihrer pom.xml vorhanden ist.

Konfigurieren des Back-End-Speicheranbieters

Durable Functions benötigt einen Speicheranbieter, um den Laufzeitzustand zu speichern. Sie können die Verwendung von Azure Storage als Speicheranbieter in local.settings.json konfigurieren, indem Sie die Verbindungszeichenfolge Ihres Azure Storage-Kontos als Wert für AzureWebJobsStorage angeben:

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

Erstellen Ihres lokalen Projekts

  1. Drücken Sie in Visual Studio Code F1 (oder STRG+UMSCHALT+P bzw. BEFEHL+UMSCHALT-P), um die Befehlspalette zu öffnen. Suchen Sie in der Befehlspalette den Befehl Azure Functions: Create New Project..., und wählen Sie ihn aus.

    Screenshot of create new functions project.

  2. Wählen Sie einen leeren Ordner für Ihr Projekt und anschließend Auswählen aus.

  3. Geben Sie an den Eingabeaufforderungen die folgenden Informationen an:

    Prompt Wert
    Sprache auswählen Klicken Sie auf die Option Java.
    Auswählen einer Java-Version Wählen Sie Java 8 oder höher aus, die Java-Version, mit der Ihre Funktionen in Azure ausgeführt werden. Wählen Sie eine Java-Version aus, die Sie lokal überprüft haben.
    Angeben einer Gruppen-ID com.function.
    Angeben einer Artefakt-ID myDurableFunction.
    Angeben einer Version 1.0-SNAPSHOT.
    Angeben eines Paketnamens com.function.
    Angeben eines App-Namens myDurableFunction.
    Auswählen des Buildtools für Java-Projekte Klicken Sie auf die Option Maven.
    Auswählen, wie Sie Ihr Projekt öffnen möchten Klicken Sie auf die Option Open in new window.

Sie verfügen jetzt über ein Projekt mit einer HTTP-Beispielfunktion. Sie können diese Funktion bei Bedarf entfernen, da wir im nächsten Schritt die grundlegenden Funktionen einer Durable Functions-App hinzufügen.

Hinzufügen von Funktionen zum Projekt

  1. Suchen Sie in der Befehlspalette den Befehl Azure Functions: Create Function..., und wählen Sie ihn aus.

  2. Wählen Sie All für Change template filter aus.

  3. Geben Sie an den Eingabeaufforderungen die folgenden Informationen an:

    Prompt Wert
    „Select a template for your function“ (Wählen Sie eine Vorlage für Ihre Funktion aus.) DurableFunctionsOrchestration
    Angeben eines Paketnamens com.function
    Angeben eines Funktionsnamens DurableFunctionsOrchestrator
  4. Wählen Sie Select storage account im Popupfenster die Option zum Einrichten von Speicherkontoinformationen aus, und folgen Sie den Aufforderungen.

Sie sollten nun die drei grundlegenden Funktionen für eine Durable Functions-App generiert haben.

Konfigurieren von pom.xml und host.json

Fügen Sie Ihrer Datei pom.xml die folgende Abhängigkeit hinzu:

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

Fügen Sie Ihrer host.json die Eigenschaft extensions hinzu.

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

Lokales Testen der Funktion

Mit Azure Functions Core-Tools können Sie ein Azure Functions-Projekt auf dem lokalen Entwicklungscomputer ausführen.

Hinweis

Durable Functions für Java erfordert Azure Functions Core Tools v4.0.4915 oder höher. Sie können die installierte Version anzeigen, indem Sie den Befehl func --version im Terminal ausführen.

  1. Wenn Sie Visual Studio Code verwenden, öffnen Sie ein neues Terminalfenster, und führen Sie die folgenden Befehle aus, um das Projekt zu erstellen:

    mvn clean package
    

    Führen Sie dann die dauerhafte Funktion aus:

    mvn azure-functions:run
    
  2. Kopieren Sie im Bereich Terminal den URL-Endpunkt Ihrer über HTTP ausgelösten Funktion.

    Screenshot of Azure local output.

  3. Senden Sie mit einem Tool wie Postman oder cURL eine HTTP-POST-Anforderung an den URL-Endpunkt. Sie sollten eine Antwort ähnlich der folgenden erhalten:

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

    Die Antwort ist das erste Ergebnis der HTTP-Funktion, um mitzuteilen, dass die dauerhafte Orchestrierung erfolgreich gestartet wurde. Es ist noch nicht das Endergebnis der Orchestrierung. Die Antwort enthält einige nützliche URLs. Zunächst fragen wir den Status der Orchestrierung ab.

  4. Kopieren Sie den URL-Wert für statusQueryGetUri, fügen Sie ihn in die Adressleiste des Browsers ein, und führen Sie anschließend die Anforderung aus. Alternativ dazu können Sie auch weiterhin Postman oder cURL verwenden, um die GET-Anforderung auszugeben.

    Mit der Anforderung wird für die Orchestrierungsinstanz der Status abgefragt. Sie sollten schließlich eine Antwort erhalten, die zeigt, dass die Instanz abgeschlossen wurde, und die die Ausgaben oder Ergebnisse der dauerhaften Funktion enthält. Er sieht wie folgt aus:

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