Java 関数を Azure Storage に接続する

Azure Functions を使用すると、独自の統合コードを記述しなくても、Azure サービスやその他のリソースを関数に接続できます。 これらのバインドは、入力と出力の両方を表し、関数定義内で宣言されます。 バインドからのデータは、パラメーターとして関数に提供されます。 "トリガー" は、特殊な種類の入力バインドです。 関数はトリガーを 1 つしか持てませんが、複数の入力および出力バインドを持つことができます。 詳細については、「Azure Functions でのトリガーとバインドの概念」を参照してください。

この記事では、前のクイック スタートの記事で作成した関数を Azure Storage キューと統合する方法を説明します。 この関数に追加する出力バインドは、HTTP 要求のデータをキュー内のメッセージに書き込みます。

ほとんどのバインドでは、バインドされているサービスにアクセスするために関数が使用する、保存されている接続文字列が必要です。 この接続を簡単にするために、関数アプリで作成したストレージ アカウントを使用します。 このアカウントへの接続は、既に AzureWebJobsStorage という名前のアプリ設定に保存されています。

前提条件

この記事の作業を始める前に、Java クイックスタートのパート 1 の手順を完了しておきます。

関数アプリの設定をダウンロードする

必要なストレージ アカウントと共に Azure で関数アプリを既に作成しました。 このアカウントの接続文字列は、Azure のアプリ設定に安全に格納されています。 この記事では、同じアカウントのストレージ キューにメッセージを書き込みます。 関数をローカルで実行しているときにストレージ アカウントに接続するには、アプリ設定を local.settings.json ファイルにダウンロードする必要があります。

プロジェクトのルートから次の Azure Functions Core Tools コマンドを実行して設定を local.settings.json にダウンロードし、<APP_NAME> を前の記事の関数アプリの名前に置き換えます。

func azure functionapp fetch-app-settings <APP_NAME>

場合によっては Azure アカウントにサインインする必要があります。

重要

このコマンドを実行すると、既存の設定が Azure の関数アプリの値で上書きされます。

local.settings.json ファイルは、機密情報が含まれているため、決して公開されず、ソース管理から除外される必要があります。

ストレージ アカウントの接続文字列である、値 AzureWebJobsStorage が必要になります。 この接続を使用して、出力バインドが期待どおりに動作することを確認します。

拡張バンドルを有効にする

バインド拡張機能をインストールする最も簡単な方法は、拡張機能のバンドルを有効にすることです。 バンドルを有効にすると、事前定義された一連の拡張機能パッケージが自動的にインストールされます。

拡張機能のバンドルを有効にするには、host.json ファイルを開き、その内容を次のコードに合わせて更新します。

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[3.*, 4.0.0)"
    }
}

これで、Storage の出力バインドをプロジェクトに追加できるようになります。

出力バインディングを追加する

Java プロジェクトでは、バインドは関数メソッドのバインド注釈として定義されます。 その後、これらの注釈に基づいて function.json ファイルが自動的に生成されます。

src/main/java の下の対象の関数コードの場所を参照し、Function.java プロジェクト ファイルを開きます。run メソッド定義に、次のパラメーターを追加します。

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

msg パラメーターの型は OutputBinding<T> であり、文字列のコレクションを表します。 これらの文字列は、関数の完了時にメッセージとして出力バインドに書き込まれます。 この場合、出力は outqueue という名前のストレージ キューです。 このストレージ アカウントの接続文字列は、connection メソッドによって設定されます。 接続文字列自体を渡すのではなく、ストレージ アカウントの接続文字列を含むアプリケーション設定を渡します。

run メソッドの定義は次の例のようになります。

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

出力バインディングを使用するコードを追加する

これで、新しい msg パラメーターを使用して、関数コードから出力バインドに書き込むことができます。 成功応答の前に次のコード行を追加して、name の値を msg 出力バインドに追加します。

msg.setValue(name);

出力バインドを使用すると、認証、キュー参照の取得、またはデータの書き込みに、Azure Storage SDK のコードを使用する必要がなくなります。 Functions ランタイムおよびキューの出力バインドが、ユーザーに代わってこれらのタスクを処理します。

run メソッドは次の例のようになります。

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

テストを更新する

アーキタイプはテストのセットも作成するため、run メソッド シグネチャ内の新しい msg パラメーターを処理するためにこれらのテストを更新する必要があります。

src/main/java の下のテスト コードの場所を参照し、Function.java プロジェクト ファイルを開きます。//Invoke の下のコード行を次のコードに置き換えます。

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

これで、新しい出力バインドをローカルで試す準備ができました。

関数をローカルで実行する

前と同様に、次のコマンドを使用してプロジェクトをビルドし、Functions ランタイムをローカルで起動します。

mvn clean package 
mvn azure-functions:run

Note

host.json で拡張バンドルを有効にしていたため、スタートアップ時にストレージ バインド拡張機能が他の Microsoft バインド拡張機能と共に自動的にダウンロードされ、インストールされました。

前と同様に、新しいターミナル ウィンドウで cURL を使用して、コマンド ラインから関数をトリガーします。

curl -w "\n" http://localhost:7071/api/HttpTrigger-Java --data AzureFunctions

今回は、出力バインドはさらにストレージ アカウントに outqueue という名前のキューを作成し、この同じ文字列のメッセージを追加します。

次に、Azure CLI を使用して新しいキューを表示し、メッセージが追加されたことを確認します。 また、Microsoft Azure Storage Explorer または Azure portal を使用してキューを表示することもできます。

ストレージ アカウントの接続を設定する

local.settings.json ファイルを開き、ストレージ アカウントの接続文字列である AzureWebJobsStorage の値をコピーします。 次の Bash コマンドを使用して、AZURE_STORAGE_CONNECTION_STRING 環境変数に接続文字列を設定します。

AZURE_STORAGE_CONNECTION_STRING="<STORAGE_CONNECTION_STRING>"

AZURE_STORAGE_CONNECTION_STRING 環境変数に接続文字列を設定すると、毎回認証情報を指定しなくても、ストレージ アカウントにアクセスできます。

ストレージ キューに対するクエリを実行する

次の例のように、az storage queue list コマンドを使用して、アカウントのストレージ キューを表示できます。

az storage queue list --output tsv

このコマンドの出力には、outqueue という名前のキューが含まれています。これは、関数の実行時に作成されたキューです。

次に、az storage message peek コマンドを使用して、このキュー内のメッセージを表示します (以下の例を参照)。

echo `echo $(az storage message peek --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`

返される文字列は、関数をテストするために送信したメッセージと同じものであるはずです。

Note

前の例では、返される文字列を base64 からデコードしています。 これは、Queue ストレージ バインドが base64 文字列として Azure Storage との間で書き込みおよび読み取りを行うためです。

プロジェクトを再デプロイする

公開したアプリを更新するには、次のコマンドを再度実行します。

mvn azure-functions:deploy

ここでも、cURL を使用して、デプロイした関数をテストすることができます。 前と同様に、次の例のように、POST 要求の本文で値 AzureFunctions を URL に渡します。

curl -w "\n" https://fabrikam-functions-20190929094703749.azurewebsites.net/api/HttpTrigger-Java?code=zYRohsTwBlZ68YF.... --data AzureFunctions

再度 Storage キュー メッセージを調べて、出力バインドが期待どおりにキューに新しいメッセージを生成することを確認できます。

リソースをクリーンアップする

このコレクションの他のクイックスタートは、このクイックスタートに基づいています。 引き続きクイックスタートまたはチュートリアルの作業を行う場合は、このクイックスタートで作成したリソースをクリーンアップしないでください。 作業する予定がない場合は、次のコマンドを使用して、このクイックスタートで作成したすべてのリソースを削除してください。

az group delete --name myResourceGroup

メッセージが表示されたら、y を選択します。

次のステップ

HTTP によってトリガーされる関数を、ストレージ キューにデータを書き込むように更新しました。 Python を使用して Azure Functions を開発する方法の詳細については、「Azure Functions の Java 開発者向けガイド」と、Azure Functions のトリガーとバインドに関するページを参照してください。 Java での完全な関数プロジェクトの例については、Java 関数のサンプルを参照してください。

次に、関数アプリに対して Application Insights の監視を有効にする必要があります。