バイナリペイロードの使用 - AWS IoT Core

バイナリペイロードの使用

メッセージのペイロードを raw バイナリデータとして (JSON オブジェクトではなく) 処理するには、* 演算子を使用して SELECT 句で参照できます。

バイナリペイロードの例

メッセージペイロードを raw バイナリデータとして参照するために * を使用するときは、ルールにデータを追加できます。空のペイロードまたは JSON ペイロードがある場合、結果のペイロードには、ルールを使用してデータを追加できます。以下は、サポートされる SELECT 句の例です

  • バイナリペイロードに * のみを使用した以下の SELECT 句を使用できます。

    • SELECT * FROM 'topic/subtopic'
    • SELECT * FROM 'topic/subtopic' WHERE timestamp() % 12 = 0
  • データを追加して、以下の SELECT 句を使用することもできます。

    • SELECT *, principal() as principal, timestamp() as time FROM 'topic/subtopic'
    • SELECT encode(*, 'base64') AS data, timestamp() AS ts FROM 'topic/subtopic'
  • これらの SELECT 句をバイナリペイロードと使用することもできます。

    • 以下は、WHERE 句の device_type を参照します。

      SELECT * FROM 'topic/subtopic' WHERE device_type = 'thermostat'
    • 以下もサポートされています。

      { "sql": "SELECT * FROM 'topic/subtopic'", "actions": [ { "republish": { "topic": "device/${device_id}" } } ] }

次のルールアクションはバイナリペイロードをサポートしていないので、それらをデコードする必要があります。

  • Lambdaアクションなど、バイナリペイロード入力をサポートしないルールアクションの場合は、バイナリペイロードをデコードする必要があります。Lambda ルールアクションは、base64 エンコード済みで JSON ペイロードの場合、バイナリデータを受け取ることができます。ルールを以下のように変更することで、これを実行できます。

    SELECT encode(*, 'base64') AS data FROM 'my_topic'
  • SQL ステートメントは、文字列を入力としてサポートしていません。文字列入力を JSON に変換するには、次のコマンドが実行できます。

    SELECT decode(encode(*, 'base64'), 'base64') AS payload FROM 'topic'

protobuf メッセージペイロードのデコード

プロトコルバッファ (protobuf) は、構造化データをコンパクトなバイナリ形式でシリアル化するために使用されるオープンソースのデータ形式です。データをネットワーク経由で送信したり、ファイルに保存したりするために使用されます。protobuf を使用すると、小さなパケットサイズで、他のメッセージング形式よりも高速でデータを送信できます。AWS IoT Coreルールは decode (value, decodingScheme) SQL 関数を提供することで protobuf をサポートしており、protobuf でエンコードされたメッセージペイロードを JSON 形式にデコードし、ダウンストリームのサービスにルーティングできます。このセクションでは、AWS IoT Core ルールで protobuf デコードを設定する手順について、順を追って説明します。

前提条件

記述子ファイルの作成

記述子ファイルが既にある場合は、このステップを省略できます。記述子ファイル (.desc) は .proto ファイルのコンパイル版で、protobuf のシリアル化で使用されるデータ構造とメッセージタイプを定義するテキストファイルです。記述子ファイルを生成するには、.proto ファイルを定義し、protoc コンパイラを使用してそれをコンパイルする必要があります。

  1. メッセージタイプを定義する .proto ファイルを作成します。.proto ファイルの例として、以下のようなものがあります。

    syntax = "proto3"; message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; }

    この例の .proto ファイルでは、proto3 構文を使用してメッセージタイプ Person を定義します。Person メッセージ定義では、3 つのフィールド (名前、ID、E メール) を指定します。.proto ファイルメッセージ形式の詳細については、言語ガイド (proto3)を参照してください。

  2. protoc コンパイラを使用して、.proto ファイルをコンパイルし、記述子ファイルを生成します。descriptor (.desc) ファイルを作成するコマンドの例として、次のものがあります。

    protoc --descriptor_set_out=<FILENAME>.desc \ --proto_path=<PATH_TO_IMPORTS_DIRECTORY> \ --include_imports \ <PROTO_FILENAME>.proto

    このコマンド例では記述子ファイル <FILENAME>.desc を生成し、AWS IoT Core ルールによって <PROTO_FILENAME>.proto で定義されたデータ構造に準拠する protobuf ペイロードをデコードするために使用できます。

    • --descriptor_set_out

      生成する記述子ファイル (<FILENAME>.desc) の名前を指定します。

    • --proto_path

      コンパイル中の .proto ファイルから参照するインポートされたファイルの場所を指定します。インポートされた .proto ファイルの場所が異なる場合は、フラグを複数回指定できます。

    • --include_imports

      インポートされた .proto ファイルもすべてコンパイルして、<FILENAME>.desc 記述ファイルに含めるように指定します。

    • <PROTO_FILENAME>.proto

      コンパイルする .proto ファイルの名前を指定します。

    protoc リファレンスの詳細については、API リファレンスを参照してください。

記述子ファイルを S3 バケットにアップロードする

記述子ファイル <FILENAME>.desc を作成したら、AWS API、AWS SDK、または AWS マネジメントコンソール を使用して、Amazon S3 バケットに記述子ファイル <FILENAME>.desc をアップロードします。

重要な考慮事項

  • 記述子ファイルは、ルールを設定するのと同じ AWS リージョン にある AWS アカウント の Amazon S3 バケットにアップロードしてください。

  • 必ず、AWS IoT Core に S3 から FileDescriptorSet を読み取るためのアクセス権限を付与してください。S3 バケットでサーバー側の暗号化が無効になっている場合、または S3 バケットが Amazon S3 管理キー (SSE-S3) を使用して暗号化されている場合、追加のポリシー設定は必要ありません。これは、バケットポリシーの例で実現できます。

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "s3:Get*", "Resource": "arn:aws:s3:::<BUCKET NAME>/<FILENAME>.desc" } ] }
  • S3 バケットが AWS Key Management Service キー (SSE-KMS) を使用して暗号化されている場合、S3 バケットにアクセスする際ににキーを使用する AWS IoT Core アクセス権限を必ず付与してください。そのためには、次のステートメントをキーポリシーに追加してください。

    { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }

ルールで protobuf デコードを設定する

記述子ファイルを S3 バケットにアップロードしたら、decode(value, decodingScheme) SQL 関数を使用して、protobuf メッセージペイロード形式をデコードできるルールを設定します。詳細な関数の署名と例は、「AWS IoT SQL リファレンス」の「decode(value, decodingScheme) SQL 関数」に記載されています。

decode(value, decodingScheme) 関数を使用する SQL 式の例としては、次のようなものがあります。

SELECT VALUE decode(*, 'proto', '<BUCKET NAME>', '<FILENAME>.desc', '<PROTO_FILENAME>', '<PROTO_MESSAGE_TYPE>') FROM '<MY_TOPIC>'

この式の例:

  • decode(value, decodingScheme) SQL 関数を使用して、* から参照されるバイナリメッセージペイロードをデコードします。これは、protobuf でエンコードされたバイナリのペイロード、または base64 でエンコードされた protobuf ペイロードを表す JSON 文字列です。

  • 提供されたメッセージペイロードは、PROTO_FILENAME.proto で定義されている Person メッセージタイプを使用してエンコードされます。

  • BUCKET NAME という名前の Amazon S3 バケットには、PROTO_FILENAME.proto から生成された FILENAME.desc が含まれます。

設定が完了したら、ルールが登録されているトピックに関するメッセージを AWS IoT Core に公開します。

制限

AWS IoT Core ルールは、次の制限付きで protobuf をサポートしています。

  • 置換テンプレート内の protobuf メッセージペイロードのデコードはサポートされていません。

  • protobuf メッセージペイロードをデコードする場合、1 つの SQL 式内で decode SQL 関数を最大 2 回使用できます。

  • インバウンドペイロードの最大サイズは 128 KiB (1KiB = 1024 バイト)、アウトバウンドペイロードの最大サイズは 128 KiB、Amazon S3 バケットに保存される FileDescriptorSet オブジェクトの最大サイズは 32 KiB です。

  • SSE-C 暗号化を使用して暗号化された Amazon S3 バケットはサポートされていません。

ベストプラクティス

ここでは、ベストプラクティスおよびトラブルシューティングのヒントを説明します。

  • Amazon S3 バケットに proto ファイルをバックアップする。

    問題が発生した場合に備えて、proto ファイルをバックアップすることをお勧めします。例えば、protoc の実行中にバックアップせずに proto ファイルを誤って変更すると、本稼働スタックで問題が発生する可能性があります。Amazon S3 バケットのファイルをバックアップする方法は複数あります。例えば、S3 バケットでバージョニングを使用できます。Amazon S3 バケット内のファイルをバックアップする方法の詳細については、「Amazon S3 デベロッパーガイド」を参照してください。

  • ログエントリを表示するように AWS IoT ロギングを設定する。

    CloudWatch でアカウントの AWS IoT ログを確認できるように AWS IoT ロギングを設定することをお勧めします。ルールの SQL クエリによって外部関数を呼び出すと、AWS IoT Core ルールによって eventTypeFunctionExecution のログエントリを生成します。これにはトラブルシューティングに役立つ理由フィールドが含まれています。Amazon S3 オブジェクトが見つからない、または無効な protobuf ファイル記述子が含まれていることが考えられます。AWS IoT ロギングを設定する方法とログエントリを確認する方法の詳細については、「AWS IoT ロギングの設定」と「ルールエンジンのログエントリ」を参照してください。

  • 新しいオブジェクトキーを使用して FileDescriptorSet を更新し、ルール内のオブジェクトキーを更新する。

    更新された記述子ファイルを Amazon S3 バケットにアップロードすることで FileDescriptorSet を更新できます。FileDescriptorSet への更新が反映されるまで、最大 15 分かかる場合があります。この遅延を避けるため、新しいオブジェクトキーを使用して更新した FileDescriptorSet をアップロードし、ルール内のオブジェクトキーを更新することをお勧めします。