3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure Events Hubs に Event を送信するための便利ツール

Posted at

はじめに

この記事を読んでくださっている皆様は、Azure Event Hubs にイベントを送信するために、何を使っていますか?私は、Azure Functions でイベントを送信するコードを書くことが多いです。

しかし、イマイチコードを書く気分でない日もあります。そんな日に、ふと Azure Event Hubs にイベントを送信したくなったらどうでしょう。検証作業は滞ってしまいますよね。え?そんな日はない?まぁまぁそう言わずに!

そこで、今回は追加のコード不要で Azure Event Hubs に Event を送信できる便利ツール EventHubDataGenerator をご紹介します。

この記事のゴール

EventHubDataGenerator から Azure Event Hubs にイベントを送信し、Azure Functions でイベントを取得する、という構成を確認します。ローカルに環境を構築すると、 EventHubs Connection String と Event Hub 名を指定するだけでイベントを送信することが可能になります。

image.png

前提条件

本手順では、以下のツールが必要となります。必要に応じてインストールしてください。

  • 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 を選択します。

スクリーンショット 2021-09-02 0.47.32.png

v1 を選択します。

スクリーンショット 2021-09-02 0.47.40.png

コンテナが起動したことを確認します。

$ 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 にアクセスし、起動したコンテナに接続します。

image.png

あとは、ここに Event Hub Connection String と Event Hub Namespace を指定するだけで、簡単にイベントを送信することができます。簡単ですね!

3. Azure Event Hubs に送信されたイベントの確認

実際に Azure Functions を使って、イベントが送信されていることを確認します。

なお、以下に示すのは、一部のコードです。詳細は、こちら のリポジトリに公開しているので、適宜ご参照ください。

また、local.settings.json の Azure Event Hubs への接続文字列は、適切な値に置き換えてください。下記はサンプルです。

local.settings.sample.json
{
    "IsEncrypted": false,
    "Values": {
      "AzureWebJobsStorage": "UseDevelopmentStorage=true",
      "FUNCTIONS_WORKER_RUNTIME": "java",
      "realtimedatastreaming_RootManageSharedAccessKey_EVENTHUB": "Endpoint=sb://xxxxxxxxxx.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
}

以下の Function を実行し、送信されたイベントを確認します。

EventHubTrigger.java
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));
    }
}

イベントは下記の通り取得できます。

sample.log
[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 に対してイベントを送信する方法をご紹介しました。ぜひぜひ皆さんも検証時に活用してみてください!

参考

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?