Azure ServiceBus キューにREST APIでメッセージを入れたいときもある 

この記事は「[NEXTSCAPE Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nextscape)」15日目の記事です。

みなさま、クリスマスの定番「[シュトーレン](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%A5%E3%83%88%E3%83%AC%E3%83%B3)」を食べたことはありますか？あの白い粉をうまくこぼさずに攻略する方法があれば、そちらを記事にしたい今日このごろです。

現在、ServiceBus キューを拾ってLogicAppsから別システムのSQL Databaseへデータを連携する機能を開発しています。
テスト用にとPostmanからREST APIをたたいてキューにメッセージを追加しようとしたところ、SAS Tokenの付与で意外とハマってしまいました。
その辺のまとめとして、今回はAzure ServiceBus キューにREST APIでメッセージを追加する方法をご紹介したいと思います。

## この記事でわかること
- Postmanを利用したAzure ServiceBusキューのSAS Tokenを生成する方法
- Postmanを利用したAzure ServiceBusキュー RestApiへのメッセージ送信方法

## 前提条件
- ServiceBusについては事前に作成が行われている前提となり、本稿ではキューの作成から記載しています。
- APIリクエストには[Postman](https://www.postman.com/)を利用しています。

## ServiceBusの設定

### キューを作成する
#### 1. ServiceBusへメッセージ送信のためにキューを作成します。
"sample"という名前でキューを追加しました。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/e8c2cbeb-f45c-cb20-29e0-bf76d1ce0540.png)
#### 2. 次に作成したキューを選択し、共有アクセスポリシーを追加します。
"send"という名称で送信のみチェックを入れて追加しました。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/5d0d06a7-b9e5-fe1e-031c-39fabc3e05d9.png)
#### 3. 共有アクセスポリシーを追加すると、キーが発行されます。
SASトークンの発行にはこちらの主キーを利用します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/18bf0992-ebdb-2b08-ecfc-594a9e58baf1.png)

これでServiceBus キュー側の準備は完了しました。

## SAS Tokenの詳細
送信するSAS Tokenのフォーマットとパラメータは以下となります。
このトークンを生成して、REST APIを呼び出すときにPOSTリクエストのAuthorizationヘッダへ付与します。

```
SharedAccessSignature sig=<signature-string>&se=<expiry>&skn=<keyName>&sr=<URL-encoded-resourceURI>
```

| パラメータ名 | 詳細 |
|:--|:--|
| se | トークンの有効期限。 エポック 1970 年 1 月 1 日 00:00:00 UTC (UNIX エポック) からトークンの期限が切れるまでの秒数を示す整数。 |
| skn | 承認規則の名前。 |
| sr | アクセスされているリソースの URI。 |
| sig | 署名|


## Postmanの設定
### PostmanでServiceBusキューへのPOSTリクエストを作成する

- メソッドはPOSTを選択します
- 送信先のURLにはServiceBusの**"URL + キュー名 + messages"**で記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/3b4e6b60-128c-56f1-9e01-d5f689228d96.png)

### Pre-request Scriptを利用してSAS Tokenを生成する
Pre-request ScriptにはJavaScriptを記載することができるので、けっこういろいろなことが出来ます。
では設定方法を確認していきましょう。

#### 1. Pre-request Scriptを開き、SAS Token生成用のコードを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/e9a55a82-4990-5513-f963-8e226b3b6b0c.png)
以下がコードとなります。**resourceUri, keyName, key**にはさきほど作成した環境の値をセットしてください。
生成したSAS Tokenは、Postmanの環境変数内に'SASToken'のキー名で追加しました。

```JavaScript
// ServiceBusキューのUri
var resourceUri = 'https://********.servicebus.windows.net/sample/';
// 共有アクセスポリシーのポリシー名
var keyName = 'send';
// 共有アクセスポリシーの主キー
var key = '******************************';

// 有効期限の生成
var now = new Date();
var week = 60 * 60 * 24 * 7;
var ttl = Math.round(now.getTime() / 1000) + week;

// signatureの生成
var encodedUri = encodeURIComponent(resourceUri)
var signature = encodedUri + '\n' + ttl;
var sigByte = CryptoJS.HmacSHA256(signature, key);
var sigBase64 = CryptoJS.enc.Base64.stringify(sigByte);

// SAS Tokenの生成
pm.globals.set('SASToken', 'SharedAccessSignature sr=' + encodedUri + '&sig=' +  encodeURIComponent(sigBase64) + '&se=' + ttl + '&skn=' + keyName);
```

#### 2. Headersにパラメータを追加します。
KeyとValueに以下のパラメータを追加します。
{{SASToken}}は、Pre-request Scriptで追加したPostmanの環境変数内にあるSASTokenを取得します。

| KEY |  VALUE |
|:--|:--|
| Authorization | {{SASToken}} |
| Content-Type| application/json |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/1170d892-5865-1eea-2104-dbcb12e60f89.png)
これでSAS Tokenの生成を行う設定は完了です。


## SASトークンを利用したREST APIによるメッセージ送信
### 送信するメッセージの作成
Bodyを開き、rawを選択してJSON文字列を記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/a6c605fc-da6a-6069-85ac-9e5968cfc6b4.png)

### メッセージの送信
Sendボタンをクリックして、ServiceBusキューにメッセージを送信します。
SAS Tokenの生成がうまくいけば、以下のように201 Createdが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/937ea0de-592f-0af7-98fc-ebd8c820f2cb.png)

### キューを確認する
送信したメッセージがキューに送信されていることを確認します。
受信でメッセージを開くとキューから削除されてしまいますので、念のためピークで開きます。

Azureポータルからメッセージを送信したServiceBusを選択し、**Service Bus Explorer --> ピーク**を開きます。
先ほど送信したメッセージが格納されているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/15a9546e-aacf-2461-e582-94facbcc5c92.png)
ピークをクリックしてメッセージを確認すると、先ほどPOSTで送信したメッセージが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192656/35217725-5244-0221-e951-bb3cb8818966.png)

## 参考情報
- [メッセージを送信する](https://docs.microsoft.com/ja-jp/rest/api/servicebus/send-message-to-queue)
- [Shared Access Signature による Service Bus のアクセスの制御](https://docs.microsoft.com/ja-jp/azure/service-bus-messaging/service-bus-sas#generate-a-shared-access-signature-token)
- [SAS トークンの生成](https://docs.microsoft.com/ja-jp/rest/api/eventhub/generate-sas-token)

## まとめ
実はこの記事、一度はC#のコンソールアプリでSAS Tokenの発行をするという内容で書き終えました(汗)
ですが、ふと思いついてPre-request Scriptを利用したらPostmanだけで完結できてしまったので、修正して現在の記事となっています。
普段の開発ではSDK経由でキューへメッセージ送信を行うため、あまりREST API経由でメッセージを投げる機会は無いかもしれません。
お役にたつか微妙な記事となってしまいましたが、Postmanでお手軽にテストを行いたい時などにご参考頂ければ幸いです。

余談ですが、現在取り組んでいる機能開発は**Dynamics365-->ServiceBusキュー-->LogicApps-->SQL Database**といった流れでデータを連携します。
次回があれば、その辺のお話をご紹介したいなと思っています。

では。