5

Play 2.1.1 とその組み込みの JPA 統合 (JPA.em() など) を使用しています。

  • db.pass プロパティを動的に変更するにはどうすればよいですか? Play.application().configuration() は Play 2.1 の時点で不変のようです。(または、少なくともミューテーターを認識していません)
  • db.pass を変更できる場合、JPA.em() が新しいパスワードを使用して EntityManager を返すように、DB 構成を再ロードするにはどうすればよいでしょうか?

回避しようとしているのは、EntityManagerFactory を使用して EntityManager を再作成する必要があることです。JPA ヘルパー クラスで、引き続き Play に管理させたいと考えています。

バックグラウンド

システムには、ローカルで実行するためのデフォルトの DB 構成があります。サーバーにデプロイされると、次のスクリプトを使用して実行中のアプリケーションに DB パスワードが動的に設定されます。

#!/bin/bash 
stty -echo 
read -p "Password: " PASS 
stty echo 
curl -k https://127.0.0.1:8443/someUrl/pwd --data "password=$PASS" 

アプリケーションはこのデータを受け取り、Hibernate SessionFactory を再作成します。私たちの新しい Play アプリは、同様のことを行う必要があります。

4

2 に答える 2

6

重要なのは、ConfigFactory を使用して新しい Config エントリを作成することです。この新しい構成には、パスワード サービスへの http 呼び出しからの値を持つパスワードのエントリが含まれています。

新しい構成を使用して新しい構成が作成され、元の構成から元の構成にフォールバックします。

基本的に、新しいパスワード エントリは元のパスワードに取って代わります。

あなたがそれを言うと、長くなりますが、コードはかなり読みやすいです。

public class Global extends GlobalSettings {

    // inject http client to make call for password

    @Override
    public Configuration onLoadConfig(Configuration configuration, File file, ClassLoader classLoader) {
        final Config config = ConfigFactory.parseString(String.format("db.default.user=%s", callPasswordService()));

        return new Configuration(config.withFallback(configuration.getWrappedConfiguration().underlying()));
    }
}
于 2013-06-18T06:37:18.463 に答える
3

私自身の質問に答えるために、最初に Configuration.onLoadConfig を次のようにオーバーライドすることで、実行時に不変の構成を更新する問題を解決しました。

  1. 構成が production.level が PROD であることを示している場合
  2. stdin からパスワードを読み取る
  3. 古い構成をマップに変換し、ConfigFactory.parseMap と新しいパラメーターを使用して新しい構成を構築することにより、新しい構成を作成します。
  4. super.onLoadConfig を返す

ただし、これでも DB 構成の再ロードの問題は解決されませんでした。最終的に、同僚が Play! を作成しました。プラグインは、本質的にいくつかの JPA クラスのコピーであり、構成プロパティのマップで再ロードされる機能が追加されています。

アップデート

「フック」は、プラグインが JPA クラスに追加する追加の静的メソッドです (reloadWithProperties など)。このメソッドは、JNDI で再バインドされる新しいデータ ソースを作成します。

于 2013-05-20T18:49:43.997 に答える