IBM Cloudantを使用するSpring BootのWebアプリを作成し、Cloud Foundryにデプロイする

IBM Cloudantを使いたいと思うことあるかもしれませんが、QiitaにはNodeRedの記事が多いですね。。。
javaで使いたい人向けの記事があまりないので入門編として掲載します。
また、IBMのCloud Foundryにデプロイするまで書きます。

## dependency 
Spring boot 2.0.4
cloudant-client 2.12.0
okhttp3 3.11.0 
※ okhttp3についてjava 1.7以上が必須なので、パフォーマンスなどを気にしなければ省いても良い

## cloudantの認証について
cloudantの認証も以前はHMAC keyを発行しなければならなかったのですが、
2018/08/21　現在ではHMAC、VCAP_SERVICES、IAM API key、 ローカル認証やaccount endpoint？など多彩な認証によって認証が可能なようです。

どの認証方式でも良いのですが、今回はローカル環境とCloud Foundry環境の違いを気にすることなくかけるVCAP_SERVICESを利用します。
## Cloud FoundryとCludantの接続、VCAP_SERVICEの取得
Cludantを起動してCloud Foundryに接続し、VCAP_SERVICESに接続するまでを記載します。

### Cloudantを作成する

cloudantを作成します。
![cloudant-0.png](https://qiita-image-store.s3.amazonaws.com/0/155890/6bb105b7-9f20-3a7f-d8ac-7ee8453db966.png)
![cloudant-2.png](https://qiita-image-store.s3.amazonaws.com/0/155890/2be526da-7090-48d0-85cb-a73bb3ccac4e.png)
できたらDashboardにアクセスしDBを作成してデータを登録します。
![cloudant-3.png](https://qiita-image-store.s3.amazonaws.com/0/155890/36530e1a-d5c3-8302-0161-d52df1003c32.png)

### Cloud Foundryを作成しCloudantを接続する

Cloud Foundryを作成します。サービスはあとで書き換えますが一応Tomcatで作成しています。
![cf-0.png](https://qiita-image-store.s3.amazonaws.com/0/155890/60c2e7c6-f137-de50-1403-024389e81d0b.png)
![cf-1.png](https://qiita-image-store.s3.amazonaws.com/0/155890/647873a1-c0ca-7155-1112-452c9c2a12f3.png)

作成できたらCloudantを接続します。

![cf-2.png](https://qiita-image-store.s3.amazonaws.com/0/155890/54224da0-42f0-ab99-c445-859777dae3a2.png)
![cf-3.png](https://qiita-image-store.s3.amazonaws.com/0/155890/37e0e61c-7fa2-8b36-16d3-7020a3641083.png)

とりあえずIAMを自動作成します。
![cf-4.png](https://qiita-image-store.s3.amazonaws.com/0/155890/42665b3f-bb5d-6012-3669-353278cd11c7.png)

指示に従ってアプリを再起動します。
![cf-5.png](https://qiita-image-store.s3.amazonaws.com/0/155890/b8c8961a-29fa-aa13-d32b-8289f2d11fc0.png)
![cf-6.png](https://qiita-image-store.s3.amazonaws.com/0/155890/c7214c84-71d7-a4c7-4710-05ee8bcbc3f5.png)


### VCAP_SERVICESを取得する
Cloud Foundryにアクセスし、Runtimeのタブを開くとEnvironment Variablesの項目にVCAP_SERVEICEが作成されています。
![cf-7.png](https://qiita-image-store.s3.amazonaws.com/0/155890/b82dff09-addc-ba9c-2049-a34880210bc1.png)

application.ymlやapplication.propertiesに登録する際は、JSONの改行を消して１行にして記載しましょう！

## 実装

propertiesファイルにVCAP_SERVEICESを１行にしたものを記載します。[1](#cloud-foundryとcludantの接続vcap_serviceの取得)
また、この設定でCloud Foundry環境にデプロイした場合、変数の優先度の関係でローカルではpropertiesの変数、本番ではCloud Foundryの変数が使われるようになり良い感じに開発できます。

```properties:application.properties
VCAP_SERVICES={ YOUR_VCAP_SERVICES_JSON : YOUR_JSON_PROPERTIES }
```

```java:CloudantConfiguration.java
@Configuration
public class CloudantConfiguration {

    @Value("${VCAP_SERVICES}")
    private String vcapService;

    @Bean
    public CloudantClient cloudantClient()  {
        return ClientBuilder.bluemix(vcapService).build();
    }

}
```

受け取るDaoを作成していない場合はJsonObjectで受け取るのが良いです。
cloudantのライブラリがデフォルトで使用しているclassなので問題なく動作します。

```java:CloudantdemoApplication.java
@RestController
@SpringBootApplication
public class CloudantdemoApplication {

	@Autowired
	CloudantClient cloudantClient;

	public static void main(String[] args) {
		SpringApplication.run(CloudantdemoApplication.class, args);
	}

	@RequestMapping("/")
	public String index() {
		Database db = cloudantClient.database("users",false);
		QueryResult<JsonObject> result  = db.query(new QueryBuilder(eq("name","LLENN")).build(), JsonObject.class);
		return result.getDocs().toString();
	}
}
```

```$ mvn spring-boot:run```などでアプリを実行し、curlを投げると以下のように返却されます。

```bash
$ curl http://localhost:8080/
[{"_id":"18f6e5d603317e7a8189513270bc6e28","_rev":"1-487469bb37faf2e391ce4f8897b54e75","name":"LLENN"}]
```

## Cloud Foundryにデプロイする

pom.xmlでwarを出力するように設定し、
ソースコードをビルドします。

```bash
$ mvn -DskipTests=true package
```

作成した環境にデプロイします。
[IBM Cloud CLI](https://console.bluemix.net/docs/cli/index.html)のbxコマンドを使用します。

```bash
# bx コマンドでログインします。
$ bx login

# cloud foundryの環境を選択します。
$ bx target --cf

# アプリの一覧を取得します。
$ bx cf apps

名前           要求された状態   インスタンス   メモリー   ディスク   URL
Cludant-Demo   started          1/1            768M       1G         Cludant-Demo.mybluemix.net

# アプリをCloud Foundryにデプロイします。
$ bx cf push Cludant-Demo -p ./target/cloudantdemo-0.0.1-SNAPSHOT.war -b https://github.com/cloudfoundry/java-buildpack.git
...
...
     状態   開始日時               CPU    メモリー       ディスク     詳細
#0   実行   2018-09-01T00:00:00Z   0.0%   1.1M of 768M   1.3M of 1G   
```
自動でCloud Foundryが起動されるので、URLにcurlでアクセスしてみます。

```bash
$ curl https://Cludant-Demo.mybluemix.net/
[{"_id":"18f6e5d603317e7a8189513270bc6e28","_rev":"1-487469bb37faf2e391ce4f8897b54e75","name":"LLENN"}]
```

確認が終わったら停止させておきましょう。

```bash
$ bx cf stop Cludant-Demo
```


## 備考
ソースコードは以下です。
https://github.com/amanoese/cloudant-demo

## 参考
https://console.bluemix.net/docs/cli/index.html
https://github.com/cloudant/java-cloudant