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

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

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

最も基本的な Durable Functions アプリには、以下の 3 つの関数が存在します。

  • オーケストレーター関数: 他の関数を調整するワークフロー。
  • アクティビティ関数: オーケストレーター関数によって呼び出される関数で、作業を実行し、必要に応じて値を返します。
  • クライアント関数 - オーケストレーター関数を開始する、Azure の通常の関数。 この例では、HTTP によってトリガーされる関数を使用しています。

このクイックスタートでは、この "hello world" アプリを作成するさまざまな方法について説明します。 ページの上部にあるセレクターを使用して、好みのアプローチを設定してください。

前提条件

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

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

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

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

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

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

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

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

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

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>

必要な 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)"
  }
}

Note

現時点で、Java 用の Durable Functions に対する必要なサポートがあるのは、Azure Functions v4 拡張機能バンドルのみであることに注意してください。 Java 用の Durable Functions は、v3 および初期の拡張機能バンドルではサポート "されていません"。 拡張機能バンドルの詳細については、拡張機能バンドルに関するドキュメントを参照してください。

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

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

関数を作成する

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

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 アプリの基本的な関数を持つプロジェクトを生成します。

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

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

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

これで、基本的な Durable Functions アプリに含まれる 3 つの関数を持つローカル プロジェクトが作成されました。

pom.xml ファイルで com.microsoft:durabletask-azure-functions が依存関係として設定されていることを確認します。

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

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

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

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

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

    新しい関数の作成プロジェクト コマンドのスクリーンショット。

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

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

    Prompt アクション
    言語を選択する Java を選択します。
    Select a version of 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」と入力します。
    Select the build tool for Java project (Java プロジェクトのビルド ツールを選択してください) [Maven] を選択します。
    Select how you would like to open your project (プロジェクトを開く方法を選択してください) [新しいウィンドウで開く] を選択します。

これで HTTP 関数の例を含むプロジェクトが作成されました。 次の手順では Durable Functions アプリの基本的な関数を追加するため、この関数は必要に応じて削除できます。

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

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

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

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

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

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

pom.xml と host.json を構成する

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

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

以下のように host.json ファイルに extensions プロパティを追加します。

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

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

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

Note

Durable Functions for Java には、Azure Functions Core Tools バージョン 4.0.4915 以降が必要です。 ターミナルで func --version コマンドを実行することで、どのバージョンがインストールされているかを確認できます。

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

    mvn clean package
    

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

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

    Azure ローカル出力のスクリーンショット。

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