はじめに
この記事を読んでくださっている皆様は、Azure Event Hubs にイベントを送信するために、何を使っていますか?私は、Azure Functions でイベントを送信するコードを書くことが多いです。
しかし、イマイチコードを書く気分でない日もあります。そんな日に、ふと Azure Event Hubs にイベントを送信したくなったらどうでしょう。検証作業は滞ってしまいますよね。え?そんな日はない?まぁまぁそう言わずに!
そこで、今回は追加のコード不要で Azure Event Hubs に Event を送信できる便利ツール EventHubDataGenerator をご紹介します。
この記事のゴール
EventHubDataGenerator から Azure Event Hubs にイベントを送信し、Azure Functions でイベントを取得する、という構成を確認します。ローカルに環境を構築すると、 EventHubs Connection String と Event Hub 名を指定するだけでイベントを送信することが可能になります。
前提条件
本手順では、以下のツールが必要となります。必要に応じてインストールしてください。
- Microsoft Azure Subscription
- java 8 or higher
- Storage Emulator (インストール方法はこちら)
- Docker 20.10.7
- Visual Studio Code (Docker 拡張機能インストール済み)
手順
1. Azure Event Hubs、Azure Functions の作成
Azure Event Hubs、Azure Functions の詳細な作成手順は本記事では割愛します。なお、今回はパーティション数 32
の Event Hub を作成しています。
詳細な手順は、下記の Docs をご参照ください。
2. EventHubDataGenerator のインストール
ターミナルから下記コマンドを実行し、Docker Image を Pull します。
$ docker pull jalaluddin7/fakerapp:v1
v1: Pulling from jalaluddin7/fakerapp
4fe2ade4980c: Pull complete
c245f6a8ecc5: Pull complete
82bdc9503d50: Pull complete
6227b595540d: Pull complete
6bf9374bd0c1: Pull complete
a3de6b8808da: Pull complete
d12737c13302: Pull complete
Digest: sha256:856c22de4dd5466a5d4ef4aa7573263ce022d8987de5329dd3e26fc45f83f8d0
Status: Downloaded newer image for jalaluddin7/fakerapp:v1
上記で Pull した Docker Image をベースとしたコンテナを作成し、Run します。今回は、Visual Studio Code にインストールした拡張機能を使うことにします。
jalaluddin7/fakerapp
を選択します。
v1
を選択します。
コンテナが起動したことを確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c75e98e82af jalaluddin7/fakerapp:v1 "/bin/sh -c 'node in…" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp suspicious_villani
http://localhost:3000 にアクセスし、起動したコンテナに接続します。
あとは、ここに Event Hub Connection String と Event Hub Namespace を指定するだけで、簡単にイベントを送信することができます。簡単ですね!
3. Azure Event Hubs に送信されたイベントの確認
実際に Azure Functions を使って、イベントが送信されていることを確認します。
なお、以下に示すのは、一部のコードです。詳細は、こちら のリポジトリに公開しているので、適宜ご参照ください。
また、local.settings.json
の Azure Event Hubs への接続文字列は、適切な値に置き換えてください。下記はサンプルです。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "java",
"realtimedatastreaming_RootManageSharedAccessKey_EVENTHUB": "Endpoint=sb://xxxxxxxxxx.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
以下の Function を実行し、送信されたイベントを確認します。
package com.function;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import java.util.*;
/**
* Azure Functions with Event Hub trigger.
*/
public class EventHubTrigger {
/**
* This function will be invoked when an event is received from Event Hub.
*/
@FunctionName("EventHubTrigger")
public void run(
// Event Hub 'eventhub01' has 1 partition.
@com.microsoft.azure.functions.annotation.EventHubTrigger(name = "message", eventHubName = "eventhub01", connection = "realtimedatastreaming_RootManageSharedAccessKey_EVENTHUB", consumerGroup = "$Default", cardinality = Cardinality.MANY, dataType = "string") List<String> message,
// Event Hub 'eventhub02' has 32 partitions.
// @com.microsoft.azure.functions.annotation.EventHubTrigger(name = "message", eventHubName = "eventhub02", connection = "realtimedatastreaming_RootManageSharedAccessKey_EVENTHUB", consumerGroup = "$Default", cardinality = Cardinality.MANY, dataType = "") List<String> message,
final ExecutionContext context
) {
context.getLogger().info("Length:" + message.size());
message.forEach(singleMessage -> context.getLogger().info(singleMessage));
}
}
イベントは下記の通り取得できます。
[2021-08-28T11:41:25.010Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=7b9ca2bb-c6ec-4aa7-be93-1ffdf61ffd16)
[2021-08-28T11:41:25.089Z] Length:1
[2021-08-28T11:41:25.091Z] {"sensor_id":"45","sensor_temp":76,"sensor_status":"WARN"}
[2021-08-28T11:41:25.093Z] Function "EventHubTrigger" (Id: 7b9ca2bb-c6ec-4aa7-be93-1ffdf61ffd16) invoked by Java Worker
[2021-08-28T11:41:25.119Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=7b9ca2bb-c6ec-4aa7-be93-1ffdf61ffd16, Duration=117ms)
[2021-08-28T11:41:25.307Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=719e8f22-ed7a-4edf-b0fb-638f355ae68a)
[2021-08-28T11:41:25.312Z] Length:10
[2021-08-28T11:41:25.316Z] {"sensor_id":"47","sensor_temp":66,"sensor_status":"OK"}
[2021-08-28T11:41:25.318Z] {"sensor_id":"20","sensor_temp":50,"sensor_status":"FAIL"}
[2021-08-28T11:41:25.319Z] {"sensor_id":"59","sensor_temp":85,"sensor_status":"OK"}
[2021-08-28T11:41:25.320Z] {"sensor_id":"10","sensor_temp":93,"sensor_status":"OK"}
[2021-08-28T11:41:25.321Z] {"sensor_id":"42","sensor_temp":48,"sensor_status":"WARN"}
[2021-08-28T11:41:25.322Z] {"sensor_id":"30","sensor_temp":63,"sensor_status":"OK"}
[2021-08-28T11:41:25.323Z] {"sensor_id":"14","sensor_temp":22,"sensor_status":"WARN"}
[2021-08-28T11:41:25.324Z] {"sensor_id":"40","sensor_temp":61,"sensor_status":"OK"}
[2021-08-28T11:41:25.324Z] {"sensor_id":"55","sensor_temp":46,"sensor_status":"WARN"}
[2021-08-28T11:41:25.325Z] {"sensor_id":"37","sensor_temp":54,"sensor_status":"OK"}
[2021-08-28T11:41:25.326Z] Function "EventHubTrigger" (Id: 719e8f22-ed7a-4edf-b0fb-638f355ae68a) invoked by Java Worker
[2021-08-28T11:41:25.328Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=719e8f22-ed7a-4edf-b0fb-638f355ae68a, Duration=21ms)
[2021-08-28T11:41:25.909Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=8a1a31ef-a3b7-4516-952f-aead5a46f747)
[2021-08-28T11:41:25.917Z] Length:10
[2021-08-28T11:41:25.926Z] {"sensor_id":"29","sensor_temp":93,"sensor_status":"OK"}
[2021-08-28T11:41:25.929Z] {"sensor_id":"65","sensor_temp":53,"sensor_status":"FAIL"}
[2021-08-28T11:41:25.934Z] {"sensor_id":"56","sensor_temp":96,"sensor_status":"WARN"}
[2021-08-28T11:41:25.943Z] {"sensor_id":"38","sensor_temp":97,"sensor_status":"FAIL"}
[2021-08-28T11:41:25.946Z] {"sensor_id":"20","sensor_temp":35,"sensor_status":"FAIL"}
[2021-08-28T11:41:25.949Z] {"sensor_id":"4","sensor_temp":38,"sensor_status":"FAIL"}
[2021-08-28T11:41:25.958Z] {"sensor_id":"57","sensor_temp":49,"sensor_status":"OK"}
[2021-08-28T11:41:25.960Z] {"sensor_id":"26","sensor_temp":21,"sensor_status":"WARN"}
[2021-08-28T11:41:25.962Z] {"sensor_id":"13","sensor_temp":31,"sensor_status":"OK"}
[2021-08-28T11:41:25.965Z] {"sensor_id":"70","sensor_temp":35,"sensor_status":"OK"}
[2021-08-28T11:41:25.977Z] Function "EventHubTrigger" (Id: 8a1a31ef-a3b7-4516-952f-aead5a46f747) invoked by Java Worker
[2021-08-28T11:41:25.984Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=8a1a31ef-a3b7-4516-952f-aead5a46f747, Duration=76ms)
[2021-08-28T11:41:26.363Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=bdd31c10-468a-4d13-983d-ebb801a0a7d5)
[2021-08-28T11:41:26.373Z] Length:10
[2021-08-28T11:41:26.376Z] {"sensor_id":"52","sensor_temp":62,"sensor_status":"WARN"}
[2021-08-28T11:41:26.378Z] {"sensor_id":"96","sensor_temp":41,"sensor_status":"OK"}
[2021-08-28T11:41:26.382Z] {"sensor_id":"19","sensor_temp":50,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.384Z] {"sensor_id":"35","sensor_temp":42,"sensor_status":"OK"}
[2021-08-28T11:41:26.386Z] {"sensor_id":"61","sensor_temp":93,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.389Z] {"sensor_id":"45","sensor_temp":21,"sensor_status":"WARN"}
[2021-08-28T11:41:26.391Z] {"sensor_id":"42","sensor_temp":36,"sensor_status":"OK"}
[2021-08-28T11:41:26.393Z] {"sensor_id":"45","sensor_temp":58,"sensor_status":"WARN"}
[2021-08-28T11:41:26.395Z] {"sensor_id":"80","sensor_temp":100,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.396Z] {"sensor_id":"81","sensor_temp":82,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.398Z] Function "EventHubTrigger" (Id: bdd31c10-468a-4d13-983d-ebb801a0a7d5) invoked by Java Worker
[2021-08-28T11:41:26.400Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=bdd31c10-468a-4d13-983d-ebb801a0a7d5, Duration=38ms)
[2021-08-28T11:41:26.662Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=63516233-49ca-49fe-8631-31fc7a398db4)
[2021-08-28T11:41:26.670Z] Length:10
[2021-08-28T11:41:26.672Z] {"sensor_id":"1","sensor_temp":61,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.674Z] {"sensor_id":"80","sensor_temp":63,"sensor_status":"WARN"}
[2021-08-28T11:41:26.676Z] {"sensor_id":"33","sensor_temp":75,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.678Z] {"sensor_id":"77","sensor_temp":77,"sensor_status":"OK"}
[2021-08-28T11:41:26.679Z] {"sensor_id":"83","sensor_temp":31,"sensor_status":"OK"}
[2021-08-28T11:41:26.680Z] {"sensor_id":"35","sensor_temp":95,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.681Z] {"sensor_id":"80","sensor_temp":39,"sensor_status":"OK"}
[2021-08-28T11:41:26.683Z] {"sensor_id":"52","sensor_temp":97,"sensor_status":"WARN"}
[2021-08-28T11:41:26.685Z] {"sensor_id":"88","sensor_temp":37,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.686Z] {"sensor_id":"84","sensor_temp":88,"sensor_status":"OK"}
[2021-08-28T11:41:26.687Z] Function "EventHubTrigger" (Id: 63516233-49ca-49fe-8631-31fc7a398db4) invoked by Java Worker
[2021-08-28T11:41:26.689Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=63516233-49ca-49fe-8631-31fc7a398db4, Duration=27ms)
[2021-08-28T11:41:26.959Z] Executing 'Functions.EventHubTrigger' (Reason='(null)', Id=166bf77b-1b32-4246-a729-3d4fa948279c)
[2021-08-28T11:41:26.963Z] Length:9
[2021-08-28T11:41:26.965Z] {"sensor_id":"79","sensor_temp":91,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.966Z] {"sensor_id":"45","sensor_temp":25,"sensor_status":"OK"}
[2021-08-28T11:41:26.967Z] {"sensor_id":"65","sensor_temp":59,"sensor_status":"WARN"}
[2021-08-28T11:41:26.968Z] {"sensor_id":"32","sensor_temp":67,"sensor_status":"OK"}
[2021-08-28T11:41:26.969Z] {"sensor_id":"60","sensor_temp":27,"sensor_status":"WARN"}
[2021-08-28T11:41:26.971Z] {"sensor_id":"19","sensor_temp":23,"sensor_status":"OK"}
[2021-08-28T11:41:26.973Z] {"sensor_id":"88","sensor_temp":34,"sensor_status":"WARN"}
[2021-08-28T11:41:26.975Z] {"sensor_id":"97","sensor_temp":79,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.976Z] {"sensor_id":"62","sensor_temp":51,"sensor_status":"FAIL"}
[2021-08-28T11:41:26.977Z] Function "EventHubTrigger" (Id: 166bf77b-1b32-4246-a729-3d4fa948279c) invoked by Java Worker
[2021-08-28T11:41:26.979Z] Executed 'Functions.EventHubTrigger' (Succeeded, Id=166bf77b-1b32-4246-a729-3d4fa948279c, Duration=19ms)
カンタンに Azure Event Hubs に対してイベントを送信できました!
おわりに
今回は、EventHubDataGenerator を使って簡単に Azure Event Hubs に対してイベントを送信する方法をご紹介しました。ぜひぜひ皆さんも検証時に活用してみてください!