flashbackを使う

<!---


--->

この内容は [flashback](https://github.com/linkedin/flashback) を使ってみるために[README](https://github.com/linkedin/flashback/blob/master/README.md) に記載されていることをやった備忘録です。


> Flashback is designed to mock HTTP and HTTPS resources, like web services and REST APIs, for testing purposes. It records HTTP/HTTPS requests and plays back a previously recorded HTTP transaction—which we call a "scene"—so that no external connection to the internet is required in order to complete testing.

[翻訳] フラッシュバックは、WebサービスやREST APIなどのHTTPとHTTPSリソースをモックします。 HTTP/HTTPSリクエストを記録し、以前に記録されたHTTPトランザクション（「シーン」と呼ばれる）を再生します。これにより、テストを実行するためにインターネットに外部接続する必要はありません。

> Note: The flashback and flashback scene are used for testing purpose only. Each scene contains a list of Http request and response. Those http request and response might contain some sensitive data such as api key, secret, token etc. You'd better either blacklist them using customized match rule or mask them.

[翻訳] Note: フラッシュバックおよびフラッシュバックシーンは、テスト用途でのみ使用できます。各シーンには、HTTPリクエストとレスポンスのリストが含まれています。これらのHTTPリクエストとレスポンスには、api key、secret、tokenなどの機密データが含まれている可能性があります。

引用：https://github.com/linkedin/flashback#introducing-flashback

flashbackはHTTPリクエストを記録して、記録したリクエストを再生できるテスト用のプロキシです。テスト時にリクエストを再生できるので使い道があるかと思い、起動してみることにしました。

READMEの手順に従ってインストールしていきます。

```
$ git clone https://github.com/linkedin/flashback.git
```

flaskbackディレクトリに移動します。

```
$ cd flashback
```

READMEの手順に従って startAdminServer.sh を実行します。

```
$ ./startAdminServer.sh -port 1234
Downloading https://services.gradle.org/distributions/gradle-2.13-all.zip
....
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
HttpServer running on port 1234. Press any key to stop server
> Building 95% > :flashback-admin:startAdminServer
```

gradlewによって必要なパッケージがインストールされます。必要であればgradleもインストールされます。

```
> Building 95% > :flashback-admin:startAdminServer
```

この行が表示されている状態がFlashBack AdminServerが起動している状態です。


プロキシの開始をするにはHTTPリクエストをFlashBack AdminServerに送ります。

```
	curl "http://localhost:1234/admin?action=startFlashback" --data @proxy-start.json

```

```
{
	  "sceneMode": "record",
	  "sceneName": "test1",
	  "matchRule": "matchEntireRequest",
	  "scenePath": "/tmp",
	  "proxyHost": "localhost",
	  "proxyPort": "5555"
}

```

次のような意味合いのようです。

| パラメータ | 意味 |
|:-:|:-:|
| sceneMode | モード(record/playback) |
| sceneName | sceneファイル名 |
| matchRule | ??? |
| scenePath | sceneファイルを出力するディレクトリのパス |
| proxyHost | プロキシのホスト名 |
| proxyPort | プロキシのポート番号 |


`action=startFashback` でリクエストを送るとプロキシが起動します。そのプロキシを経由してリクエストを送信してみます。

```
	curl http://www.example.org -x localhost:5555 -X GET

```

プロキシを通ったリクエストは `scenePath`/`sceneName` に書き込まれます。


```書き込まれたリクエスト
{
  "NAME" : "test1",
  "HTTPEXCHANGELIST" : {
    "HTTPEXCHANGE1" : {
      "UPDATETIME" : "19 Mar 2017 09:56:29 GMT",
      "HTTPREQUEST" : {
        "HTTPMETHOD" : "GET",
        "HTTPURI" : "http://www.example.org/",
        "HTTPHEADERS" : {
          "Host" : "www.example.org",
          "User-Agent" : "curl/7.43.0",
          "Accept" : "*/*",
          "Proxy-Connection" : "Keep-Alive"
        },
        "BINARYHTTPBODY" : ""
      },
      "HTTPRESPONSE" : {
        "HTTPSTATUSCODE" : 200,
        "HTTPHEADERS" : {
          "Accept-Ranges" : "bytes",
          "X-Cache" : "HIT",
          "Cache-Control" : "max-age=604800",
          "Etag" : "\"359670651\"",
          "Server" : "ECS (rhv/818F)",
          "Vary" : "Accept-Encoding",
          "Expires" : "Sun, 26 Mar 2017 09:56:29 GMT",
          "Last-Modified" : "Fri, 09 Aug 2013 23:54:35 GMT",
          "Content-Length" : "1270",
          "Date" : "Sun, 19 Mar 2017 09:56:29 GMT",
          "Content-Type" : "text/html"
        },
        "STRINGHTTPBODY" : "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"
      }
    }
  }
}
```

プロキシの停止もHTTPリクエストで行います。

```
	curl "http://localhost:1234/admin?action=shutDownFlashback" --data '{}'

```

保存したリクエストの再生もHTTPリクエストで行います。sceneModeをplaybackにすると再生になります。


```
	curl "http://localhost:1234/admin?action=startFlashback" --data @playback.json

```

```json:playback.json
{
	  "sceneMode": "playback",
	  "sceneName": "test1",
	  "matchRule": "matchEntireRequest",
	  "scenePath": "/tmp",
	  "proxyHost": "localhost",
	  "proxyPort": "5555"
}

```