クイックスタート: Java Durable Functions アプリを作成する

Azure Functions の機能であるDurable Functionsを使用して、サーバーレス環境でステートフル関数を記述します。 Durable Functionsは、アプリケーションの状態、チェックポイント、再起動を管理します。

このクイック スタートでは、JavaでDurable Functions アプリを作成してテストします。

基本的なDurable Functions アプリには、次の 3 つの機能があります。

  • オーケストレーター関数 (Cities): 他の関数を調整するワークフロー。
  • アクティビティ関数 (Capitalize): オーケストレーターが作業を実行し、値を返すために呼び出す関数。
  • クライアント関数 (StartOrchestration): オーケストレーターを開始する HTTP によってトリガーされる関数。

このクイック スタートでは、3 つのセットアップ パスを提供します。 ページの上部にあるセレクターを使用して、好みの方法を選択します。

  • 手動セットアップ: プロジェクト構造を完全に制御するために、各ファイルを手動で作成します。
  • Maven コマンド: Maven アーキタイプを使用して、1 つのコマンドでプロジェクトをスキャフォールディングします。
  • Visual Studio Code: VS Code Azure Functions 拡張機能を使用して、ガイド付き UI を使用してプロジェクトを生成します。

前提条件

このクイック スタートを完了するには、次のものが必要です。

  • Java Developer Kit バージョン 8 以降がインストールされていること。

  • Apache Maven バージョン 3.0 以降がインストールされていること。

  • 最新バージョンの Azure Functions Core Tools

    Azure Functions 4.x では、Core Tools バージョン 4.0.4915 以降が必要です。

  • データをセキュリティで保護する HTTP テスト ツール 。 詳細については、「HTTP テスト ツール」を参照してください。

  • Visual Studio CodeAzure Functions 拡張子がインストールされています (Visual Studio Code セットアップ パスにのみ必要)。

  • Azure のサブスクリプション。 Durable Functionsを使用するには、Azure Storage アカウントが必要です。

Azure アカウントをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

必要な依存関係とプラグインをプロジェクトに追加する

pom.xml ファイルに次のコードを追加します。 コピーする前に、 your-unique-app-name をグローバルに一意の関数アプリ名に置き換えます。 環境に合わせて regionjavaVersionresourceGroup を調整します。

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

必要な JSON ファイルを追加する

host.json ファイルをプロジェクト ディレクトリに追加します。 次の例のように表示されます。

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

JavaのDurable Functionsには拡張機能バンドル v4 が必要です。 以前のバンドルはサポートされていません。 詳細については、 拡張機能バンドルのドキュメントを参照してください

Durable Functions には、ランタイム状態を格納するためのストレージ プロバイダーが必要です。 local.settings.json ファイルをプロジェクト ディレクトリに追加して、ストレージ プロバイダーを構成します。 プロバイダーとして Azure Storage を使用するには、AzureWebJobsStorage の値を Azure Storage アカウントの接続文字列に設定します。

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

Important

local.settings.json ファイルにはシークレットを含めることができます。 ソース管理にコミットされないように、.gitignore ファイルに追加するようにしてください。

Durable Functions オーケストレーター、アクティビティ、クライアント関数を作成する

次のサンプル コードは、各種類の関数の基本的な例を示しています。

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

Maven コマンドを使用してローカル Durable Functions プロジェクトを作成する

次のコマンドを実行して、Durable Functions アプリの基本的な関数を持つプロジェクトを生成します。

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

プロンプトで、次の情報を指定します。

プロンプト アクション
groupId com.function」と入力します。
artifactId myDurableFunction」と入力します。
version 1.0-SNAPSHOT を選択します。
package com.function」と入力します。
Y Y」と入力し Enter キーを押して確定します。

これで、基本的な Durable Functions アプリに含まれる 3 つの関数を持つローカル プロジェクトが作成されました。 アーキタイプには、com.microsoft:durabletask-azure-functionsの依存関係としてが自動的に含まれます。

Durable Functions用にバックエンド ストレージ プロバイダーを構成する

Durable Functions には、ランタイム状態を格納するためのストレージ プロバイダーが必要です。 local.settings.json 内で Azure Storage をストレージ プロバイダーとして設定することができます。 次の例のように、ご利用の Azure ストレージ アカウントの接続文字列を AzureWebJobsStorage に対する値として使用します。

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

Important

local.settings.json ファイルにはシークレットを含めることができます。 ソース管理にコミットしないように、 必ず .gitignore ファイルに追加してください。

ローカル プロジェクトを作成する

  1. Visual Studio Codeで F1 キーを押します (または Ctrl/Cmd + Shift + P キーを押して) コマンド パレットを開きます。 プロンプト (>) で、「Azure Functions: 新しいプロジェクトの作成を入力して選択します。

     Visual Studio Code コマンド パレットの Azure Functions [新しいProjectの作成] コマンドのスクリーンショット。

  2. を選択し、を参照します。 [フォルダーの選択] ダイアログで、プロジェクトに使用するフォルダーに移動し、[選択] を選択します。

  3. プロンプトで、次の情報を指定します。

    プロンプト アクション
    Select a language (言語を指定してください) Java を選択します。
    Java Java 8 以降を選択します。 Azure 内で関数を実行する Java バージョンと、ローカルで検証したバージョンを選択します。
    Provide a group ID (グループ ID を指定してください) com.function」と入力します。
    Provide an artifact ID (成果物 ID を指定してください) myDurableFunction」と入力します。
    Provide a version (バージョンを指定してください) 1.0-SNAPSHOT」と入力します。
    Provide a package name (パッケージ名を指定してください) com.function」と入力します。
    Provide an app name (アプリ名を指定してください) myDurableFunction」と入力します。
    Java プロジェクトのビルド ツールを選択します [Maven] を選択します。
    プロジェクトを開く方法を選択してください [新しいウィンドウで開く] を選択します。

これで HTTP 関数の例を含むプロジェクトが作成されました。 次の手順でDurable Functionsを追加するため、生成された HTTP 関数を削除できます。

プロジェクトへの関数の追加

  1. コマンド パレットで、「Azure Functions: 関数の作成を入力して選択します。

  2. [テンプレート フィルターの変更] では、[すべて] を選択します。

  3. プロンプトで、次の情報を指定します。

    プロンプト アクション
    関数のテンプレートを選択します DurableFunctionsOrchestration を選択します。
    Provide a package name (パッケージ名を指定してください) com.function」と入力します。
    関数に名前を指定します DurableFunctionsOrchestrator」と入力します。
  4. ダイアログで、[ストレージ アカウントの選択] を選択してストレージ アカウントを設定した後、プロンプトに従います。

これで、Durable Functions アプリの 3 つの基本的な関数が作成されたはずです。

Durable Functionsの pom.xml と host.json を構成する

pom.xml ファイルに次の依存関係を追加します。

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

host.jsonextensions プロパティを追加します。 ファイルに既に他のプロパティがある場合は、 extensions ブロックを既存の JSON にマージします。

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

関数をローカルでテストする

Azure Functions Core Tools を使用すると、ローカル開発コンピューターでAzure Functions プロジェクトを実行できます。

  1. Visual Studio Code を使用している場合は、新しいターミナル ウィンドウを開き、次のコマンドを実行してプロジェクトをビルドします。

    mvn clean package
    

    次に、以下のように持続的関数を実行します。

    mvn azure-functions:run
    
  2. ターミナル パネルで、HTTP によってトリガーされる関数の URL エンドポイントをコピーします。

    ローカル Azure Functions runtime の HTTP エンドポイント URL を示すターミナル出力のスクリーンショット。

  3. HTTP テスト ツールを使用して、URL エンドポイントに HTTP POST 要求を送信します。

    応答は、次の例のようになります。

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

    応答は、HTTP 関数の最初の結果です。 これによって、持続的オーケストレーションが正常に開始されたことがわかります。 オーケストレーションの最終的な結果はまだ表示されません。 応答には、いくつかの便利な URL が含まれています。 ここでは、オーケストレーションの状態のクエリを実行します。

  4. statusQueryGetUri の URL 値をコピーし、それをブラウザーのアドレス バーに貼り付け、要求を実行します。 別の方法として、引き続き HTTP テスト ツールを使用して GET 要求を発行することもできます。

    この要求によって、オーケストレーション インスタンスの状態が照会されます。 次の例のように、インスタンスが完了し、持続的関数の出力または結果が内部に含まれていることを確認できます。

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