Spring Boot3.X系 でAzure FunctionsのEventGrid Triggerを実装する手順を示す。
プロジェクトの作成は以下の記事参照。
SpringBoot2.X系の実装方法は以下の記事参照。
EventGridTriggerのイベント情報を保持するクラスの作成
指定したイベントが発火することでFunctionがキックされると、イベント情報が以下のようなJson形式で送られてくる。
この情報をマッピングするためのEventSchema
クラスを作成する。
※Blobファイル回りのイベントでトリガーするようにFunctionを定義していた場合、この情報の中からファイルの情報を抜き出す必要があるのでマッピングは必須となる。
「eventType」の値を確認することで、このイベント情報が何をトリガーとして送られてきたのが判断することができる。
以下のサンプルの場合、「Microsoft.Storage.BlobCreated」なので、Azure Blob Storageの指定パス上にファイルが新規で追加されたことでトリガーされたということが分かる。
[ { "topic": "/subscriptions/{subscription-id}/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/my-storage-account", "subject": "/blobServices/default/containers/my-file-system/blobs/new-file.txt", "eventType": "Microsoft.Storage.BlobCreated", "eventTime": "2017-06-26T18:41:00.9584103Z", "id": "831e1650-001e-001b-66ab-eeb76e069631", "data": { "api": "CreateFile", "clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", "requestId": "831e1650-001e-001b-66ab-eeb76e000000", "eTag": "\"0x8D4BCC2E4835CD0\"", "contentType": "text/plain", "contentLength": 0, "contentOffset": 0, "blobType": "BlockBlob", "url": "http://127.0.0.1:10000/devstoreaccount1/sample/test.zip", "sequencer": "00000000000004420000000000028963", "storageDiagnostics": { "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" } }, "dataVersion": "2", "metadataVersion": "1" } ]
作成するPOJOは公式ドキュメントを参考に作成する。
Azure Functions の Azure Event Grid トリガー
@Data public class EventSchema { /** トピック */ public String topic; /** サブジェクト */ public String subject; /** イベントタイプ */ public String eventType; /** イベント発生日時 */ public Date eventTime; /** ID */ public String id; /** データのバージョン */ public String dataVersion; /** メタデータのバージョン */ public String metadataVersion; /** データ */ public Map<String, Object> data; }
Functionクラスの作成
Functionクラスには、ファンクションごとに行いたい処理を記述する。
FunctionクラスはHandlerクラスで呼び出し処理を実装するため、DIコンテナに登録されるように「@Component
」アノテーションをクラスに付与している。
/** * EventGridTriggerの処理 */ @Component @Slf4j public class EventGridFunction implements Function<EventSchema, String> { /** * {@inheritDoc} */ @Override public String apply(EventSchema t) { log.info("たちつてと"); return t + "!!"; } }
Handlerクラスの作成
AzureFunctionの実装用に追加した「spring-cloud-function-adapter-azure」「spring-cloud-starter-function-web」のバージョン3.X系→4.x系の変更に伴い、Functionクラスを呼び出す処理の実装方法が変更となった。
※3.X系では「FunctionInvoker
」を継承して、Functionクラスを呼び出す処理を実装していたが、「FunctionInvoker
」が4.X系では非推奨となったため。
4.X系ではHandlerクラスもDIコンテナに登録し、HandlerクラスにFunctionクラスをDIする。
クラス内に定義した「@FunctionName」アノテーションを付与したメソッドの中で、Functionクラスを任意のタイミングで実行するように処理を記述する。
/** * サンプルEventGrid Trigger */ @Component public class EventGridHandler { /** {@link EventGridFunction } */ private EventGridFunction eventGridFunction; /** * コンストラクタ。 * * @param eventGridFunction * {@link EventGridFunction} */ public EventGridHandler(EventGridFunction eventGridFunction) { this.eventGridFunction = eventGridFunction; } @FunctionName("eventgrid") public void eventGridTrigger( @EventGridTrigger(name = "event") EventSchema event, ExecutionContext context) { this.eventGridFunction.apply(event); } }
トリガーの設定
トリガーの設定はアノテーションで行う。@FunctionName("eventgrid")
を付与したメソッドのパラメーターにcom.microsoft.azure.functions.annotation.EventGridTrigger
を付与する。
アノテーションの属性については以下の通り。
属性名 | 説明 |
---|---|
name | リクエストやリクエストボディのファンクションコードで使用される変数名。必須 |
dataType | パラメータ値をどのように扱うかを定義する。以下の値が設定可能。 "":値を文字列として取得し、POJOにデシリアライズしようとする(デフォルト) string:常に文字列として値を取得する binary:値をバイナリデータとして取得し、byte[]にデシリアライズしようとする |
// 記述例 public void eventGridTrigger( @EventGridTrigger(name = "event") EventSchema event, ExecutionContext context) { }
ローカルでの動作確認
EventGrid Triggerの起動には、Azure Blob Storageが必要となる。
今回は、ローカル環境で使用できるAzure Blob StorageのエミュレータであるAzuriteを使用する例を示す。
Azuriteの導入
コマンドプロンプトで以下のコマンドを実行する。
npm install -g azurite
インストール完了後にc:\\azurite
ディレクトリを作成し、以下のコマンドでAzuriteを起動する
azurite --silent --location c:\\azurite --debug c:\\azurite\\debug.log
起動すると以下のようなログが表示される
C:>azurite --silent --location c:\\azurite --debug c:\\azurite\\debug.log Azurite Blob service is starting at http://127.0.0.1:10000 Azurite Blob service is successfully listening at http://127.0.0.1:10000 Azurite Queue service is starting at http://127.0.0.1:10001 Azurite Queue service is successfully listening at http://127.0.0.1:10001 Azurite Table service is starting at http://127.0.0.1:10002 Azurite Table service is successfully listening at http://127.0.0.1:10002
起動中のAzuriteはCtrl + c
で停止できる。
ファンクションの設定
ファンクションプロジェクトのlocal.settings.jsonを開き、AzureWebJobsStorage
にUseDevelopmentStorage=true
と設定する。
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "java", "MAIN_CLASS":"jp.co.sample.functions.Application" } }
ファンクションの処理の中でAzureBlobStorageに対して処理を行っている場合、以下の接続設定を利用する。 以下はAzuriteの接続設定である。
設定 | 値 |
---|---|
アカウントキー | Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== |
アカウント名 | devstoreaccount1 |
Blobエンドポイント | http://127.0.0.1:10000/devstoreaccount1 |
Azurite起動中はMicrosoft Azure Storage Explorerの「ローカルで接続済み」->「ストレージアカウント」->「エミュレーター」で起動中のエミュレータの操作をすることも可能。
ファンクション動作確認
ファンクションの作成完了後にプロジェクトをビルドする。
gradlew azureFunctionsPackage
以下のコマンドでAzuriteを起動する
azurite --silent --location c:\azurite --debug c:\azurite\debug.log
ファンクションを起動する。
gradlew azureFunctionsRun
起動に成功すると以下のようにファンクションの一覧が表示される。
> Task :azureFunctionsRun Azure Function App's staging directory found at: C:\workspace\functions\build\azure-functions\java-template-func Azure Functions Core Tools Core Tools Version: 4.0.5198 Commit hash: N/A (64-bit) Function Runtime Version: 4.21.1.20667 Functions: eventgrid: eventGridTrigger
以下のURLにPOSTリクエストを送ることでファンクションをローカルで実行することが出来る。
http://localhost:7071/runtime/webhooks/eventgrid?functionName={ファンクション名}
その際ヘッダーに以下の2つを設定する
- Content-Type:application/json
- aeg-event-type:Notification
リクエストボディに以下のようなEventGridTriggerイベント情報を貼り付ける
[ { "topic": "/subscriptions/{subscription-id}/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/my-storage-account", "subject": "/blobServices/default/containers/my-file-system/blobs/new-file.txt", "eventType": "Microsoft.Storage.BlobCreated", "eventTime": "2017-06-26T18:41:00.9584103Z", "id": "831e1650-001e-001b-66ab-eeb76e069631", "data": { "api": "CreateFile", "clientRequestId": "6d79dbfb-0e37-4fc4-981f-442c9ca65760", "requestId": "831e1650-001e-001b-66ab-eeb76e000000", "eTag": "\"0x8D4BCC2E4835CD0\"", "contentType": "text/plain", "contentLength": 0, "contentOffset": 0, "blobType": "BlockBlob", "url": "http://127.0.0.1:10000/devstoreaccount1/sample/test.zip", "sequencer": "00000000000004420000000000028963", "storageDiagnostics": { "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" } }, "dataVersion": "2", "metadataVersion": "1" } ]