Azure Iot HubのダイレクトメソッドをREST APIから呼んでみる

# 概要

Azure Iot Hubに登録された全てのデバイスに対して、ダイレクトメソッドを実行します。

1台だけであれば、Azure Portal上から実行するのが手っ取り早いのですが、台数が多かったり、実行結果を他で使いたい場合などはAzure Portal以外から呼び出したくなります。

今回はダイレクトメソッドを実行し、結果を保存するところまでを試してみました。

# ダイレクトメソッドのREST API呼び出し

ダイレクトメソッドを呼び出す方法については、公式ドキュメントとして丁寧に記載されています。

- [IoT Hub からのダイレクト メソッドの呼び出しについて > 例](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-devguide-direct-methods#example)

```bash
curl -X POST \
  https://iothubname.azure-devices.net/twins/myfirstdevice/methods?api-version=2018-06-30 \
  -H 'Authorization: SharedAccessSignature sr=iothubname.azure-devices.net&sig=x&se=x&skn=iothubowner' \
  -H 'Content-Type: application/json' \
  -d '{
    "methodName": "reboot",
    "responseTimeoutInSeconds": 200,
    "payload": {
        "input1": "someInput",
        "input2": "anotherInput"
    }
}'
```
`SharedAccessSignature sr=iothubname.azure-devices.net&sig=x&se=x&skn=iothubowner` の部分はSAS tokenの生成を行うと、自動で作られる。

- [az iot hub > az iot hub generate-sas-token](https://docs.microsoft.com/ja-jp/cli/azure/ext/azure-cli-iot-ext/iot/hub?view=azure-cli-latest#ext-azure-cli-iot-ext-az-iot-hub-generate-sas-token)

```bash
az iot hub generate-sas-token -n {iothub_name}
```

`{iothub_name}` は適切なリソース名に書き換える。
そして、これをCloud Shellで実行すると・・

> `az iot hub: 'generate-sas-token' is not in the 'az iot hub' command group. See 'az iot hub --help'

って怒られる。
えー。

# Azure Cloud Shell 上で `generate-sas-token` を使えるようにする

まず、Cloud Shell は、Azure Portal 上の、`> _`アイコンで開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/72d89e98-3621-f8ec-0ad5-00b98fbaa734.png)

BashでもPowerShellでも使いやすい方を選択するのがいいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/efa9e430-0b8e-932e-bb1a-d9ca7650b932.png)

ログか何かを保存するのか、ストレージが必要になるようです。
ストレージ名とかは「詳細設定の表示」で設定できます。（今回はデフォルトのまま作成してみました）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/9d8313e7-abf7-7c3e-8afb-cda92d0b2d69.png)

初期化処理に少し時間が必要です。

同じようにエラーになって困っていた人の解決策を丸パクります。

- [generate-sas-token cannot be used with az iot hub command #7345](https://github.com/Azure/azure-cli/issues/7345)

```bash
az extension add --name azure-cli-iot-ext
```

エラーが出なければOK！
で、もう一度tokenを発行してみます。

```bash
az iot hub generate-sas-token -n a4f2d132-4cc0-4d6e-8737-9bff40ac4729
```

最終的にはこんな感じでできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/ba7a23fb-f8e9-757e-40c3-83c4f8fce9e6.png)

## `--du` or `--duration` に注意

tokenの有効期間はデフォルトで3600秒です。

> --du --duration
> 　Valid token duration in seconds.
> 　default value: 3600

もしも、1時間過ぎちゃうと、`unauthorized` って怒られることになりますので、ご注意ください。

## 準備完了

で、冒頭に戻って、作成したtokenを使えば、アクセスできるようになります。（下記）

```bash
curl -X POST \
  https://iothubname.azure-devices.net/twins/myfirstdevice/methods?api-version=2018-06-30 \
  -H 'Authorization: SharedAccessSignature sr=a4f2d132-4cc0-4d6e-8737-9bff40ac4729.azure-devices.net&sig=YM1USuqL5yHj%2B30GDT71xT9H%2FFuEKnjKNKf3TqUslX8%3D&se=1569424734&skn=iothubowner' \
  -H 'Content-Type: application/json' \
  -d '{
    "methodName": "reboot",
    "responseTimeoutInSeconds": 200,
    "payload": {
        "input1": "someInput",
        "input2": "anotherInput"
    }
}'
```

ちなみに `myfirstdevice` の部分はデバイス名です。

# 雑感

このあと、デバイス名の一覧を手動でとってきて、Bashでループを回しながら結果を取得しています。

が、イケてないので、デバイス名の一覧も自動で取得して、sas tokenも都度取得して・・ってとこまで自動化できれば最高だなって思っています。

以上。
ご覧いただきましてありがとうございました！