AWS IoT RuleでBase64デコードしても、Subscribeしてるクライアントには届かない

  • AWS
  • IoT
  • MQTT

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

AWS IoT CoreのTopicとRuleとActionの関係が最初よくわからなかったので整理した。

TopicとRuleとActionの役割

用語 役割
Topic デバイスがpublish/subscribeする宛先
Rule Topicに届いたメッセージをSQLライクな条件で抽出する処理
Action Ruleがヒットしたときに実行される処理(Lambda呼び出し、S3保存など)

RuleのFROM句にTopicかTopicフィルタ(+や#のワイルドカード)を書いて、条件に合致したらActionが走る、という構造。

Ruleは配信内容を書き換えない

一番引っかかったのがここ。Subscribeしているトピックに対してRuleでBase64デコードするような処理を設定していても、Subscribeしているクライアントに届くメッセージはデコード後のものにはならない。

flowchart LR
    A[Publish] --> B[Message Broker]
    B --> C[Subscribeしているクライアント]
    B --> D[Rules Engine]
    D --> E[Rule Action]

Message Brokerは受け取ったメッセージをSubscriberとRules Engineの両方に配信するけど、それぞれ独立した経路になっている。RuleはBrokerが配信するメッセージ自体を書き換えるものではなく、あくまで届いたメッセージのコピーに対して処理を行うだけ。

なのでデコードした結果をクライアントに届けたいなら、Republish ActionかLambdaから明示的にPublishする必要がある。

Lambda ActionはCBORを直接受け取れない

Lambda ActionはJSONペイロードしか渡せない仕様なので、CBORのようなバイナリデータをそのまま渡すことはできない。Base64エンコードしてJSON化する必要がある。

SELECT encode(*, 'base64') AS data FROM 'cmd/exec'

Lambda側ではBase64デコード→CBORデコードという順番で処理する。

ただしこれはRule経由の場合の話で、経路によって扱いが変わる。

経路 バイナリを直接扱えるか
Rule → Lambda Action ×(Base64+JSON経由)
SDK → Lambda Invoke ○
Lambda → MQTT Publish(IoTDataPlane) ○

SDKで直接Lambdaを呼び出す場合や、LambdaからIoTDataPlaneのPublishを呼ぶ場合は、payloadにバイト列をそのまま渡せる。

MQTT v5のRequest-Responseパターンで使う場合

デバイス側でCBORをやり取りしつつ、途中の処理だけLambdaを挟みたい場合は、MQTT v5のresponseTopic/correlationData/contentTypeを使うパターンになる。

SELECT
encode(*, 'base64') AS body,
get_mqtt_property('response_topic') AS respTopic,
get_mqtt_property('correlation_data') AS corrData
FROM 'cmd/exec'

Lambda側でBase64デコード→CBORデコード→処理→CBORエンコードし、IoTDataPlaneのPublishでresponseTopicへ返す。このときpayloadFormatIndicatorはUNSPECIFIED_BYTESを指定しておく(バイナリであることを示すEnum値で、他にUTF8_DATAがある)。

同じTopicに再Publishすると同じRuleがもう一度評価されてしまうので、リクエスト用とレスポンス用でTopicを分けておくのが無難。

Topicからルールへの流れの呼び方

これは用語として何と呼べばいいか気になったところ。AWS公式の説明では「Rules Engineがメッセージブローカーからメッセージを受け取る」というニュアンスで書かれているので、「メッセージブローカーがルールエンジンへメッセージをルーティングする」という表現がドキュメントの言い回しに近い。