状況
Play2を利用して既存サービスの管理ツールを作っていて、DB接続関係の設定ファイルを既存のサービスと同じもの(Yamlファイル)を利用したい。
独自設定用のYamlファイルはだいたいこんな感じになっています。
# db.yml hoge_db: user: hoge_user password: hogepassword database: hoge host: localhost fuga_db: user: fuga_user password: fugapassword database: fuga host: localhost ...
最初はGlobalSettingsのbeforeStart中でYamlファイルをパースしconfigurationに追記してあげれば、その後Playが追記されたDB設定を読んでくれると思っていたのですが、このconfigurationの追記の方法が調べても調べても見つかりませんでした。
そこで、configurationを追記することは一旦諦め、Play標準のDBPlugin(Playが自動で読み込む)を使わずに、自分で自分の設定ファイルを読み込むDBPluginを作ることにしたので、そのためのメモ。
やったこと
DB用のプラグインですが、標準利用されているのがplay.api.db.BoneCPPluginというもののようです。こいつのソースを読んだところ、db設定はdbConfigというフィールドに保持しているので、こいつを継承してdbConfigをオーバーライドし、独自の設定を返すようにしてやればよさそうです。
以下のようになりました。
package hogeapp.plugins import collection.JavaConversions._ import Java.util.{Map => JMap} class MyDBPlugin(app: Application) extends BoneCPPlugin(app) { override lazy val dbConfig = { // Yaml の DB設定を読み込む val dbSetting = Yaml.load("db.yml").asInstanceOf[JMap[String, JMap[String, String]]] // dbSettingをplayのconf形式にしてapp.configurationに追加したものを返す (app.configuration /: dbSetting) { case (conf, (k, v)) => conf ++ Configuration( ConfigFactory.parseString(""" db.%s = { "user" : "%s", "password" : "%s", "driver" : "com.mysql.jdbc.Driver", "url" : "jdbc:mysql://%s/%s?characterEncoding=UTF8" }""".format(k, v("user"), v("password"), v("host"), v("database")))) }.getConfig("db").getOrElse(Configuration.empty) } }
あとは、こいつを起動時に読み込むようにconf/play.pluginsに追加してあげれば良いです。 標準のDBPluginが優先度200らしかったので、199で動かすことにしました。
199:hogeapp.plugins.MyDBPlugin
これでdb.ymlの設定値でDBにつないでくれるようになりました。 ただ、少々ゴリ押し感のある方法なので、(出来ればapp.configurationの値に追加してあげたい)よりエレガントな方法をご存知な方がいたら是非ご教示願いたいです。