AWS IoT Greengrass でデバイスシャドウを参照・更新するカスタムコンポーネントを開発していて、シャドウマネージャにより管理されているローカルシャドウの状態を確認したい時がありました。
Greengrass v2 のシャドウマネージャでは、ローカルシャドウを H2 Database で管理しているため、H2 のシェルを使って確認してみることにしました。
手順
# H2 のインストール先は /opt/h2 にする
sudo mkdir /opt/h2 -p && cd /opt/h2
# H2 の jar を DL する
# 最新版をインストールするとシャドウマネージャとバージョンが合わず DB を開けなかったため、
# シャドウマネージャで利用されている 1.4.200 を DL
# バージョンはこちらから参照: https://github.com/aws-greengrass/aws-greengrass-shadow-manager/blob/main/pom.xml
sudo wget https://repo1.maven.org/maven2/com/h2database/h2/1.4.200/h2-1.4.200.jar -O h2.jar
# Greengrass コアソフトウェアが動いている状態だと DB のファイルがロックされているため、
# 一旦停止して DB を確認する
sudo systemctl stop greengrass.service
# H2 の org.h2.tools.Shell を使って、ShadowManager の作成した DB を開く
java -cp ./h2.jar org.h2.tools.Shell -url jdbc:h2:/greengrass/v2/work/aws.greengrass.ShadowManager/shadow
H2 Shell に入ったあとは、普通に SQL を叩くことができます。シャドウのドキュメントはバイナリエンコーディングされているため、デコードしてあげることで JSON として読むことができます。
-- H2 Shell のデフォルトだと横幅が狭く、 JSON が途中で trunc されてしまうので、横幅を広げる
maxwidth 10000;
-- シャドウの状態を確認
SELECT
THINGNAME,
SHADOWNAME,
UTF8TOSTRING((DOCUMENT)) AS DECODED_DOCUMENT,
VERSION,
DELETED,
UPDATETIME
FROM documents;
-- シャドウの同期状態を確認
SELECT
THINGNAME,
SHADOWNAME,
UTF8TOSTRING((LASTSYNCEDDOCUMENT)) AS DECODED_LASY_SYNCED_DOCUMENT,
LOCALVERSION,
CLOUDVERSION,
CLOUDDELETED,
CLOUDUPDATETIME,
LASTSYNCTIME
FROM sync;
すると、以下のようにローカルシャドウを読むことができます。
THINGNAME | SHADOWNAME | DECODED_DOCUMENT | VERSION | DELETED | UPDATETIME
GreengrassQuickStartCore-190f21802b8 | | {"state":{"desired":{"status":"alive"},"reported":{"welcome":"aws-iot"}},"metadata":{"desired":{"status":{"timestamp":1722048902}},"reported":{"welcome":{"timestamp":1722048902}}}} | 1 | FALSE | 1722048902
GreengrassQuickStartCore-190f21802b8 | condition | {"state":{"desired":{"tempreture":25},"reported":{"welcome":"aws-iot"}},"metadata":{"desired":{"tempreture":{"timestamp":1722048902}},"reported":{"welcome":{"timestamp":1722048902}}}} | 1 | FALSE | 1722048902
確認し終わったら、止めた Greengrass コアソフトウェアの再開も忘れず。
sudo systemctl start greengrass.service
参考
アイデアの元ネタはこちらです。Greengrass v1 の頃にはどうやら SQLite3 が使われていたようですね。