mockmockでサーバー(Nginx)にデータを送るプロジェクトを作成する 

この記事は、[mockmockアドベントカレンダー](https://qiita.com/advent-calendar/2019/mockmock)2日目の記事です。
昨日は@Kta-Mによる「[IoT開発者向け疑似データ送信サービス「mockmock」とは](https://qiita.com/Kta-M/items/aa75dfeaae9a44d2d3ee)」でした。

今日は[対応サービス・プロトコル]([https://qiita.com/Kta-M/items/aa75dfeaae9a44d2d3ee#%E9%80%A3%E6%90%BA%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E5%AF%BE%E5%BF%9C%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB](https://qiita.com/Kta-M/items/aa75dfeaae9a44d2d3ee#連携サービス対応プロトコル))の中から `独自サーバ:HTTP`でのmockmockプロジェクト作成例を紹介します。

## 今回やること
- NginxでWebサーバを準備する
- mockmockプロジェクトを作成する
- mockから簡単なjsonを送信する

## NginxでWebサーバを準備する
サーバはお手軽にAWS EC2(t2.nano)で、Amazon Linux2を使いました。
※AWSの使い方やEC2の起動、ssh接続の方法などは今回割愛させていただきます。
後ほどmockからアクセスするため、セキュリティグループのインバウンドルールでHTTPはオープンに設定をしておいてください。

### Nginxのインストール
```shell
$ sudo amazon-linux-extras install nginx1
```

### Nginxの起動
```shell
$ sudo systemctl start nginx
```

### Nginxの動作確認
<img width="800" alt="mockmock_advc_001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/8846167e-7581-7610-2d6f-5c9ed50bf10f.png">
ブラウザからEC2に設定されているPublic IPを入力して確認しておきましょう。

## mockmockプロジェクトを作成する
以下のフローはmockmockチュートリアル「[1. 簡単なjsonを送信する](https://console.mock-mock.com/docs/tutorials/simple_data)」にて、より詳しく丁寧に説明していますので、併せてご覧ください。

<img width="800" alt="mockmock_advc_002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/0a498f9d-4781-d635-2c48-ff241e4aead6.png">
mockmockにログインし、プロジェクト作成ボタンを押してください。

<img width="800" alt="mockmock_advc_004.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/9689346a-46fd-6e33-f072-888268b40f9c.png">
プロトコルとポートはHTTPと80番を、送信先ホストには先ほどNginx動作確認で使用したサーバのPublic IPを入力してください。

### ファイル認証の設定をNginxにする
mockmockではデータ送信するサーバの設定間違いを防ぐために、プロジェクト作成時に認証を通すようにしています。今回は一番シンプルなファイル認証での設定で進めます。

<img width="800" alt="mockmock_advc_005.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/4fe01077-b93e-0524-520d-cf36412e948d.png">
認証キーはmockmock側で自動で生成しますが、認証用パスは自由に設定できます。
上記設定の場合は、 `http://{PublicIP}/auth_mock`に80番ポートにGETでリクエストしたら、認証キーの文字列がレスポンスされれば、認証OKとなります。

```nginx:/etc/nginx/nginx.conf
server {
    location /auth_mock {
        return 200 '7-JKPaY7-_qy_Vx5svTzTBCv6VAvvvEr';
    }
}
```
Nginxの設定で、serverディレクティブにlocationで`/auth_mock`だった場合に、200OKと共に認証キーをレスポンスするように設定します。
通常は何かしらのアプリケーションがいると思うので、そちらでレスポンスしてもOKです。もちろん認証キーが記載された静的ファイルを置いてもよいです。

### mockmockからサーバへの疎通確認をする
<img width="767" alt="mockmock_advc_008_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/1342452b-bddb-1ccd-d848-c2b907f07900.png">
設定ができたらmockmockプロジェクト作成画面に戻って、 `疎通確認` というオレンジ色のボタンを押して、その場で確認することができます。

<img width="400" alt="スクリーンショット 2019-12-01 16.28.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/7a0e38ac-4377-6a60-d29a-a784c74f4ce5.png">
うまくいけば上記のようなアラートが表示されますので、そのまま登録ボタンを押してください。

<img width="300" alt="スクリーンショット 2019-12-01 16.25.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/fc08d55b-5e38-58f8-9564-8743fe1d9c33.png">　<img width="300" alt="スクリーンショット 2019-12-01 16.32.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/5adfbaec-5dc2-74c8-c09c-8192883c51ea.png">
なお、上記のようにエラーになった場合は、Nginxのログや設定を見直してください。ちなみにHTTPレスポンスコードは200番であることをmockmockは期待していますので、上記のように201とかだと同じくエラーになります。

＞＞ mockmockチュートリアルでは、[こちら](https://console.mock-mock.com/docs/tutorials/simple_data#create_project)に詳細説明があります。

## mockから簡単なjsonを送信する
### データテンプレートを作成する
<img width="400" alt="mockmock_advc_006.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/e4623418-bd64-e954-800f-dd39c87c41d6.png">
左メニューの「テンプレート」に右側にあるプラスボタンからテンプレート新規登録画面へ遷移できます。
<img width="400" alt="mockmock_advc_007.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/9e9f71ab-415b-7e63-6f5d-aed8ace68cf2.png">
ここで送信するデータフォーマットを定義できますが、お手元に送信したいJSONデータが無ければ登録後の画面の方が設定しやすいので、そのままでお進みください。

<img width="300" alt="mockmock_advc_011.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/a4ddcbb3-762e-59cb-b04b-7e84b669a4dd.png">　　<img width="300" alt="mockmock_advc_012.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/039b2f94-ceef-39b5-c961-18588aefccf9.png">
固定の文字列だけだと面白くないので、現在時刻も送るように設定をしてみました。
welcomeキーと同じ階層に追加する場合はその親に当たる`(ROOT)`の右にあるプラスボタンで追加してください。日時フォーマットも`%Y-%m-%dT%H:%M:%SZ`のように指定ができます。

＞＞ mockmockチュートリアルでは、[こちら](https://console.mock-mock.com/docs/tutorials/simple_data#create_data_template)に詳細説明があります。

### mockグループを作成する
<img width="400" alt="mockmock_advc_010.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/18acc956-a515-6673-6ca8-25f7c0735785.png">
左メニューの「mockグループ」の右側にあるプラスボタンから新規登録画面へ遷移できます。

<img width="400" alt="mockmock_advc_013.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/d0fd9c08-4852-3300-52ca-2589b7b1ca30.png">
`最大稼働時間`はmockの停止タイマーを設定できる機能です。mockを立てっぱなしで、想定外の利用が発生しないように用意しています。
EC2立てっぱなしとかやってしまいますよね、、、>_<
mockmockはエンジニアに優しいサービスを常に目指しています！

＞＞ mockmockチュートリアルでは、[こちら](https://console.mock-mock.com/docs/tutorials/simple_data#create_mock_group)に詳細説明があります。

### mockステータスを作成する
<img width="400
" alt="mockmock_advc_015.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/3eda3d4e-9d84-4433-e87e-305fcd2000bd.png">
上部のタブで「mockステータス」をクリックして、「mockステータス作成」から新規登録画面へ遷移します。ここでは起動したmockからデータ送信する諸々の設定をします。
パスとリクエストメソッドを任意のものに設定します。プロジェクトの認証ではGETでしたが、ここではPOSTでデータ通信するようにします。
また、送信するデータフォーマットを設定済みのデータテンプレートから選択します。今回は先ほど登録したテキストと現在時刻のものを指定します。

＞＞ mockmockチュートリアルでは、[こちら](https://console.mock-mock.com/docs/tutorials/simple_data#create_mock_status)に詳細説明があります。

### mockの作成
<img width="972" alt="mockmock_advc_016.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/380dbcdf-d24a-96a2-6d7f-5936a108bf5d.png">
まず最初にテスト送信するmockを作成する必要があるため、mock作成ボタンを1回クリックして作成してください。作成するだけではまだmockはデータ送信を開始しません。

### mockステータスの設定でリクエストを受けられるようにNginxの設定をする
```nginx:/etc/nginx/nginx.conf
server {
    location /ping {
        return 200 '{"Ping":"Pong"}';
    }
```
mockステータスで設定したデータ送信パスでレスポンスするように設定します。
※これも通常は何かしらのアプリケーションがいると思うので(ry

<img width="400" alt="mockmock_advc_018.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/90fcf93a-0695-c096-adf3-a55d1e8d80b9.png">
レスポンスコード200が返ってきたら成功です。

＞＞ mockmockチュートリアルでは、[こちら](#### ＞＞ mockmockチュートリアルでは、[こちら](https://console.mock-mock.com/docs/tutorials/simple_data#create_mock_status)に詳細説明があります。)に詳細説明があります。

### テスト送信をする
<img width="890" alt="mockmock_advc_017.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/ad94d497-2c3b-3f79-1d01-22a62841666f.png">
次に上部タブの「mockステータス」をクリックして、テスト送信をします。このとき先ほど登録したmockステータスを選択します。

### mockの起動をする
<img width="997" alt="mockmock_advc_019.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22567/929c3c98-af41-fff7-a935-c7326c9e123d.png">

上部タブの「mock管理」をクリックして、mock一覧画面でmockを起動します。

### Nginxのログを確認する
```nginx:/etc/nginx/nginx.conf
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for" '
                        '"$request_body"';
      access_log  /var/log/nginx/access.log  main;
```
POSTで送信したリクエストボディがログに出力されるように、Nginxログフォーマットに`$request_body`を追加して、再起動します。

```shell:/var/log/nginx
xx.xx.xx.xx - - [01/Dec/2019:08:08:04 +0000] "POST /ping HTTP/1.1" 200 16 "-" "mockmock/1.0.0" "-" "-"
xx.xx.xx.xx - - [01/Dec/2019:08:08:13 +0000] "POST /ping HTTP/1.1" 200 16 "-" "mockmock/1.0.0" "-" "-"
xx.xx.xx.xx - - [01/Dec/2019:08:08:23 +0000] "POST /ping HTTP/1.1" 200 16 "-" "mockmock/1.0.0" "-" "-"
xx.xx.xx.xx - - [01/Dec/2019:08:08:33 +0000] "POST /ping HTTP/1.1" 200 16 "-" "mockmock/1.0.0" "-" "-"
xx.xx.xx.xx - - [01/Dec/2019:08:08:43 +0000] "POST /ping HTTP/1.1" 200 16 "-" "mockmock/1.0.0" "-" "-"
```
ログの最後に追加したはずが、`"-"`となってしまっています。どうやらNginxは必要がない限りリクエストボディの中身を扱わないらしく、このままではログ出力されないようです。

```shell:/etc/nginx/nginx.conf
server {
    location / {
        proxy_pass http://127.0.0.1/blackhole;
    }

    location /blackhole {
        access_log off;
        return 200 '{"Ping":"Pong"}';
    }

    location /ping {
        proxy_pass http://127.0.0.1/blackhole;
    }
```
ということで、ちょっとトリッキーですが、自身にプロキシーしてリクエストボディの中身がログ出力されるようにしてみました。
※これも通常は何かしらのアプリケーションがい(ry

```shell:/var/log/nginx
xx.xx.xx.xx - - [01/Dec/2019:08:10:13 +0000] "POST /ping HTTP/1.1" 200 15 "-" "mockmock/1.0.0" "-" "{\x22welcome\x22:\x22mockmock world!\x22,\x22current_at\x22:\x222019-12-01T08:1
0:13Z\x22}"
xx.xx.xx.xx - - [01/Dec/2019:08:10:23 +0000] "POST /ping HTTP/1.1" 200 15 "-" "mockmock/1.0.0" "-" "{\x22welcome\x22:\x22mockmock world!\x22,\x22current_at\x22:\x222019-12-01T08:1
0:23Z\x22}"
xx.xx.xx.xx - - [01/Dec/2019:08:10:33 +0000] "POST /ping HTTP/1.1" 200 15 "-" "mockmock/1.0.0" "-" "{\x22welcome\x22:\x22mockmock world!\x22,\x22current_at\x22:\x222019-12-01T08:1
0:33Z\x22}"
```
無事にログ出力されるようになり、mockmockデータテンプレートで設定したフォーマットで送受信できていることが確認できました。

## まとめ
- mockmockからの疑似データをWebサーバ(Nginx)で受信、ログ出力して、送信データを確認する設定例を紹介しました。
- データ送信先サーバの設定間違いを防ぐための認証のうち、一番シンプルなファイル認証での設定を説明しました。

IoTシステムのバックエンドに独自サーバを構築している場合でも簡単にmockmockは簡単に疑似データをテスト送信できます。機能テストから負荷検証まで、デバイスが送信するデータを簡単に再現でき、エミュレータープログラムを作る手間を大幅に減らすことが可能です。
また今回紹介できませんでしたが、時系列に変化するさまざまなデータを生成するジェネレータもあり、使いこなせばかなりリアルなデバイスデータを再現できます。
これらについてはこれからのアドベントカレンダーでも（たぶん）紹介していくと思いますので、どうぞ楽しみにお待ちください。

明日は@Y_uuuです。 
AWSのIoT用バックエンドサービス「AWS IoT Core」へ疑似データを送信するmockmockプロジェクトの作り方についてです！