Compose MongoDB へ node.js からアクセスする

Bluemix の Compose MongoDB を ロカール と Bluemix CFコンテナ の Node.js からアクセスする方法についてもメモです。 Compose の MongoDBへ接続する場合、Bluemixのサービス資格情報に、暗号化通信のための鍵が提供され、それを利用して暗号化セッションを繋ぐ必要があり、少しノウハウが必要ですね。
![スクリーンショット 2017-06-28 17.21.16.png](https://qiita-image-store.s3.amazonaws.com/0/42829/c23e224e-8e75-7c10-2707-030df4e1690a.png)


# Mongodb クライアント で接続する場合

cfenv を利用して、ローカル環境では vcap-local.json で、サービス資格情報を読み込み、 CFコンテナ環境では、環境変数で取り込むためのコードです。 コード全体は https://github.com/IBM-Bluemix/compose-mongodb-helloworld-nodejs/blob/master/server.js にあります。

~~~file:server.js
//var appenv = cfenv.getAppEnv();                                                                                                        
var vcapLocal = require("./vcap-local.json");
var appEnvOpts = vcapLocal ? { vcap: vcapLocal} : {}

//var appenv = cfenv.getAppEnv();
var appenv = cfenv.getAppEnv(appEnvOpts);
~~~

# Mongoose で接続する場合
こちらも、同じくローカル環境では vcap-local.json で、サービス資格情報を読み込み、 コンテナ環境では、環境変数で取り込むためのコードです。 mongoDBに接続が成功すると、DBのリストを表示します。

~~~
#!/usr/bin/env node

var mongoose = require('mongoose');
var assert = require('assert');
var cfenv = require("cfenv");

var svc = 'compose-for-mongodb';
var vcapLocal = require("./vcap-local.json");
var appEnvOpts = vcapLocal ? { vcap: vcapLocal} : {};
var appenv = cfenv.getAppEnv(appEnvOpts);
var services = appenv.services;
var mongodb_services = services["compose-for-mongodb"];
var credentials = mongodb_services[0].credentials;
var ca = [new Buffer(credentials.ca_certificate_base64, 'base64')];

var options = {
    mongos: {
	ssl: true,
	sslValidate: true,
	sslCA: ca,
	poolSize: 1,
	reconnectTries: 1
    }
};

// コールバック　エラー時
mongoose.connection.on('error',function (err) {
  console.log('Mongoose default connection error: ' + err);
});

// コールバック  セッション確立時
mongoose.connection.on('open', function (err) {
  console.log("=== Connected to mongodb on Compose ===" );
  assert.equal(null, err);
  mongoose.connection.db.listCollections().toArray(function(err, collections) {
     assert.equal(null, err);
     collections.forEach(function(collection) {
       console.log(collection);
     });
     mongoose.connection.db.close();
     process.exit(0);
  });
});

// 接続
mongoose.connect(credentials.uri, options);
~~~

# vcap-local.json
credentials の部分を Bluemix ポータルで表示されるサービス資格情報で置き換えて利用します。

~~~
imac:mongodb_mongoose maho$ cat vcap-local.json 
{
 "services": {
  "compose-for-mongodb": [
   {
    "credentials": {
     "ca_certificate_base64": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURlekNDQW1PZ0F3SUJBZ0lFV1ZOZ0tEQU5CZ2txaGtpRzl3MEJBUTBGQURBL01UMH
<省略>
RkpObnVXQ01Fa2lZdVZoZDJoN21nekFVM2VlNVV3bmF6WHRlQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
     "db_type": "mongodb",
     "deployment_id": "******************:",
     "maps": [],
     "name": "**************************",
     "uri": "mongodb://*****:***********@sl-us-south-1-portal.3.dblayer.com:17599,sl-us-south-1-portal.4.dblayer.com:17599/admin?ssl=true",
     "uri_cli": "mongo --ssl --sslAllowInvalidCertificates sl-us-south-1-portal.3.dblayer.com:17599/admin -u admin -p ***************"
    },
    "label": "compose-for-mongodb",
    "name": "Compose for MongoDB-no",
    "plan": "Standard",
    "provider": null,
    "syslog_drain_url": null,
    "tags": [
     "big_data",
     "data_management",
     "ibm_created"
    ],
    "volume_mounts": []
   }
  ]
 }
}
~~~

# まとめ
Compose mongodb は、ローカル環境で接続できないかと、心配したのですが、これで解決しました。よかったー（笑)



# 参考資料

* Mongoose, Node and Compose https://help.compose.com/docs/connecting-to-mongodb#section-nodejs-native
* GitHub IBM-Bluemix/compose-mongodb-helloworld-nodejs https://github.com/IBM-Bluemix/compose-mongodb-helloworld-nodejs
* Hosted MongoDB https://www.compose.com/mongodb