GridDB CloudとMicrosoft Azureを使用してサーバーレスのIoT Hubを作成する

GridDBの主な魅力の1つは、ユニークなキー・コンテナ型データモデルとメモリファーストのデータアーキテクチャにより、IoTシステムの管理に本質的な強みを持っていることです。これを念頭に、IoTデバイスとイベント処理にはAzureのIoT Hub、データストレージにはGridDB Cloudを使用して、クラウド上で完全にIoTシステムを構築する方法をご紹介したいと思います。これを管理する最も簡単な方法は、Azure Functions を使用して、IoT Hub デバイスから HTTP リクエスト経由でデータを送信することです。

この記事では、Azure IoT Hub 用の VS Code 拡張機能を使用して、IoT Hub を使用した仮想デバイスの作成、テスト、管理に必要なすべてのリソースを作成します。また、Azure CLI Tools を利用して、GridDB Cloud でホワイトリスト化する可能性のある IP アドレスの一覧を取得します。 最後に、Azure Functions をいくつか作成し(VS Code を使用)、作成した Azure Functions を Azure サブスクリプションにデプロイし、Iot Hub と連携させます。 繰り返しになりますが、このプロジェクトの目的は、デバイスがデータを送信し、イベントをトリガーし、データペイロードを GridDB Cloud にシームレスに送信することです。

実装

次に、このプロジェクトを動作させる方法について説明します。

前提条件

この手順に従うには、Microsoft Azureのアカウントとクレジット(残念ながら、無料で利用開始することはできません)が必要です。また、GridDB Cloudの無料トライアルも必要です。最も安価なIoT Hubは、月額10ドルと見積もられています。

必須ではありませんが、この記事では、VS Code および Azure CLI ツール を使用して多くの操作を実行する方法を紹介します。

Azure リソースの作成

それでは、Azure リソースを作成してみましょう。 作成する必要があるのは以下のものです。

  1. Azure IoT Hub
  2. 仮想デバイス
  3. Azure Functions

Azure IoT Hub の作成

これはメインのハブであり、イベントトリガーと仮想デバイスのワンストップショップとなります。新しいハブを作成するには、Azure Webポータル(簡単)またはVS Code拡張機能(より簡単)を使用して作成できます。

VS Codeでビルドするには、まず適切な拡張機能をインストールします。<、リージョン、サブスクリプション、グローバルに一意の名前(ハブは一意である必要があり、独自のパブリック向けDNS名が割り当てられるため)が含まれます。

ハブへの仮想デバイスの追加

次に、仮想IoTデバイスを追加します。もう一度コマンドパレットを開き、「Azure IoT Hub: Create Device」を選択してデバイス名を指定します。好きなだけデバイスを追加できますが、今回は1つのデバイスにしておきます。このデバイスからハブにデータを送信する方法については、後ほど説明します。

イベントの監視用Azure Functionsの作成

最後に、Azure Functions を利用して、デバイスの監視を行い、変更を検出します。イベントが検出されたら、次に何を行うかを制御できるようにしたいと思います。今回は、HTTP リクエストを送信します。

そのためには、もう1つ VS Code 拡張機能が必要です。Azure Functions

そして、もう一度コマンドパレットを開き、「Azure Functions: Create Function App in Azure…」を選択して関数を作成します。この段階では、関数に名前を付け、ローカルインスタンスを作成し、実行環境を選択します。今回は、利用可能な最新のnode.jsのバージョンを選択しました。

Azure 内のイベント監視システムの動作に関する詳細は、以下のドキュメントを参照してください。 https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-event-grid

GridDB Cloud へのデータペイロードの送信

リソースが準備できたら、次のステップはイベント監視の設定です。ハブがデバイスのいずれかがデータを送信したことを検知した際には、ハブがデータペイロードのHTTPリクエストを送信するようにします。これを行うには、前ステップで作成したAzure Functionとイベント監視を使用します。

Azure Function: イベントがトリガーされた場合のソースコード

このステップに必要なソースコードはすでに作成済みですので、上記で示したようにリポジトリをクローンしてください。コードは非常にシンプルです。Azureが作成したeventGridTriggers用のサンプルコードを基に、トリガーが発動されるたびにHTTPリクエストを行うコンポーネントを追加するだけです。ソースコードは以下のようになります。

const { app } = require('@azure/functions');
const axios = require('axios');
require('dotenv').config()

app.eventGrid('eventGridTrigger1', {
    handler: (event, context) => {
        context.log('Event grid function processed event:', event);

        const container = 'azureTest'
        const auth = {
            username: process.env.CLOUD_USERNAME,
            password: process.env.CLOUD_PASSWORD
        }
        const headers = {
            'Content-Type': 'application/json'
        }

        //HTTP Request to create our container called azureTest
        const dataCreation = {
            "container_name": container,
            "container_type": "COLLECTION",
            "rowkey": false,
            "columns": [
                { "name": "test", "type": "STRING" }
            ]
        }
        const configCreation = {
            method: 'POST',
            maxBodyLength: Infinity,
            url: process.env.CLOUD_URL + "/containers",
            headers,
            data: dataCreation,
            auth
        }

        axios.request(configCreation)
            .then((response) => {
                context.log(response.statusText);
                context.log(JSON.stringify(response.data));
            })
            .catch((error) => {
                context.log(error);
                context.error(error)
            });

        //HTTP Request to send data to our container
        const data = JSON.stringify([
            ["GRID EVENT TRIGGERED"]
        ]);

        let config = {
            method: 'PUT',
            maxBodyLength: Infinity,
            url: process.env.CLOUD_URL + "/containers/" + container + "/rows",
            headers,
            data,
            auth
        };

        axios.request(config)
            .then((response) => {
                context.log(response.statusText);
                context.log(JSON.stringify(response.data));
            })
            .catch((error) => {
                context.log(error);
                context.error(error)
            });
    }
});

GridDB Cloud Web API を使用して、保存するペイロードを送信するための HTTP リクエストを構築します。 準備がすべて整ったので、Azure Cloud にファンクションをデプロイします。.

env-exampleファイルをコピーして.env` にリネームし、値を自分で記入する必要があります。 CLOUD URL 変数には、GridDB Portal から GridDB WebAPI URL をそのままコピーしてください。

Azure クラウドへの Azure Function のデプロイ

ここで、もう一度、上記の指定のリポジトリにこのブログで提供されたソースコードがあることを確認し、VS Code のカレントフォルダー/プロジェクトがソースコードのあるディレクトリ内にあることを確認してください。

次に、コマンドパレットで「Azure Functions: Deploy to Function App」を選択し、上で作成したファンクションを選択します。これにより、現在の作業ディレクトリ(つまり、この記事のリポジトリからダウンロードしたすべてのソースコード)のzipファイルが作成され、Azureアカウントに直接デプロイされます。次に、このソースコードをIoT Hubとテスト用仮想デバイスに関連付けます。

Azure Function を IoT Hub に結びつける

最後のステップとして、前ステップで作成した Azure Function をハブで利用できるようにします。このステップでは、Azure Web ポータルを使用します。

ポータルを開き、IoT Hub リソースを見つけます。そのページ内で、イベント -> Azure Function に移動します。新しいイベントを作成するので、名前とシステム トピックを指定します。「イベント タイプのフィルタ」ボックスでは、「デバイス テレメトリ」のみを選択したままにしておきます。最後に、「エンドポイントの設定」をクリックします。

サイドパネルでは、ほとんどの場合、すべて自動入力されますが、そうでない場合は、以前に作成したAzure機能アプリと機能を選択します(例:関数名:eventGridTrigger1)。 注:この機能を使用するには、アカウントのサブスクリプションページでレジストリ Microsoft.EventGrid を有効にする必要があります。

IoT ハブからのデータ受信

最後に、デバイスからハブに何らかのペイロードのイベントをトリガーしたとしても、HTTP リクエストは失敗します。これは、GridDB Cloud がすべての受信 IP アドレスをホワイトリストに登録する必要があるためです。

ここで問題となるのは、私たちがイベントの処理に軽量なAzure Functionを使用しており、固定IPアドレスを持つ本格的なサーバー/VMを使用していないことです。幸い、Azure Functionで使用されている可能性のあるすべてのIPアドレスを取得する方法があります。次のドキュメントを参照してください:https://learn.microsoft.com/en-us/azure/azure-functions/ip-addresses

Azure CLI をインストールし、適切なアカウント/サブスクリプションにログインする必要があります。ログイン後、以下のコマンドを実行します。

$ az functionapp show --resource-group <INSERT RESOURCE NAME> --name <INSERT AZURE FUNCTION NAME> --query possibleOutboundIpAddresses --output tsv > outbound.txt

これにより、約40の可能なIPアドレスのリストが出力され、outbound.txtというテキストファイルに保存されます。これらすべてをGridDB Cloud Whitelistに追加すれば、イベントが発生するたびに、すべてのイベントを正常に保存できるようになります。

ホワイトリストのIPアドレス

もちろん、これらのIPアドレスを一つ一つ手書きで入力することは技術的には可能ですが、退屈で恐ろしい作業になるでしょう。bashのシンプルな「do while」ループでこれらを追加するには、まずすべての認証ヘッダーを含むエンドポイントを取得する必要があります。

これを行うには、GridDB Cloud Webポータルを開き、開発者コンソールを開き、ネットワークタブに移動し、XHRリクエストをフィルタリングしてすべてクリアし、リストにある40のIPアドレスのいずれかを追加します。

When you hit submit, you will see a 201 POST Request, now do the following: right click -> Copy Value -> Copy as cURL. You will now have the cURL Command saved in your clipboard.

「whitelistIp.sh」スクリプトを開き、「runCurl」スクリプト内の末尾のIPアドレスを除いた部分に、お客様専用のエンドポイントを入力します。以下がスクリプト全体の例です。

#!/bin/bash

file=$1

#EXAMPLE
#runCurl() {
# curl 'https://cloud57.griddb.com/mfcloud57/dbaas/web-api/contracts/m01wc1a/access-list' -X POST -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0' -H 'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br, zstd' -H 'Content-Type: application/json;charset=utf-8' -H 'Access-Control-Allow-Origin: *' -H 'Authorization: Bearer eyJ0eXAiOiJBY2Nlc3MiLCJIUzI1NiJ9.eyJzdWIiOiJkMTg4NjlhZC1mYjUxLTQwMWMtOWQ0Yy03YzI3MGNkZTBmZDkiLCJleHAiOjE3MzEwMTEyMTMsInJvbGUiOiJBZG1pbiIsInN5c3RlbVR5cGUiOjF9.B1MsV9-Nu8m8mJbsp6dKABjJDBjQDdc9aRLffTlTcVM' -H 'Origin: https://cloud5197.griddb.com' -H 'Connection: keep-alive' -H 'Referer: https://cloud5197.griddb.com/mfcloud5197/portal/' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'Priority: u=0' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' --data-raw $1
#}

runCurl() {
    <paste VALUE HERE> $1
}

while IFS= read -r line; do
    for ip in ${line//,/ }; do
        echo "Whitelisting IP Address: $ip"
        runCurl $ip
    done
done < "$file"</paste>

このスクリプトは、Azure CLIコマンドからの出力をIPアドレスの文字列に変換し、カンマで区切った後、個々のアドレスに対してcURLコマンドを実行します。このスクリプトは、実行時にCLI引数としてファイル名を必要とします。例:$ ./whitelistIp.sh outbound.txt

デバイスからクラウドへのデータ送信

すべての設定が完了したので、最後に仮想デバイスからクラウドにデータを送信します。すると、GridDB Cloudインスタンスにテスト文字列が公開されるはずです。ソースコードでは、インフラストラクチャが期待通りに動作することを確認するためのテストとして、「GRID EVENT TRIGGERED」という文字列を含む文字列を、azureTestという新しいコンテナに単純に保存しています。

VS Code ウィンドウのエクスプローラー タブで、Azure IoT Hub リソース パネルを見つけ、IoT Hub マネージャーとデバイスを見つけます。使用するデバイスを右クリックして、[IoT Hub に D2C メッセージを送信](D2C = デバイスからクラウド)を選択します。

メッセージが送信されると、GridDB Cloudインスタンスに「azureTest」という新しいコンテナが作成され、その中に「GRID EVENT TRIGGERED」という値を持つ1つのデータ行が作成されます。素晴らしいです。

image-7

結論

以上です。これで、クラウドIoTインフラストラクチャを好きなだけ拡張できるようになりました。実際のデバイスに結びついた実際のスキーマで新しいデータコンテナを作成し、それらを同期して、すべてのデータをGridDB Cloudに保存して、純粋にサーバーレスな体験をお楽しみください!

ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb

Leave a Reply

Your email address will not be published. Required fields are marked *