2013-04-18 76 views
4

我們正在使用Play 2.1.1及其內置的JPA集成(JPA.em() 等)。如何在運行時更改Play 2 Framework DB配置?

  • 我們如何動態更改db.pass屬性? Play.application()。configuration()似乎 在Play 2.1中是不可變的。 (或者我們至少不知道增變器)
  • 如果我們能夠更改db.pass,我們如何重新加載數據庫配置,以便JPA.em()使用新密碼返回一個EntityManager?

我們試圖避免的是必須使用 EntityManagerFactory重新創建EntityManager。我們希望繼續讓Play在 中管理JPA幫助程序類。

背景

該系統具有本地運行一個默認的數據庫配置。當部署到服務器,數據庫密碼是動態上運行的應用程序使用以下腳本設置:

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

應用收到這樣的數據,然後重新創建休眠 SessionFactory的。我們新的Play應用將被要求做類似 的事情。

回答

2

要回答我的問題,首先我們通過與覆蓋Configuration.onLoadConfig解決在運行時更新不可改變配置的問題如下:

  1. 如果配置指示production.level是PROD
  2. 從標準輸入讀取密碼
  3. 通過將舊配置轉換爲地圖並使用ConfigFactory.parseMap構建新配置並使用新參數創建新配置
  4. 返回super.onLoadConfig

但是,這仍然沒有解決重新加載數據庫配置的問題。最後,我的同事創建了一個Play!插件,它基本上是一些JPA類的副本,增加了用配置屬性映射重新加載的能力。

更新

的「鉤」是插件添加到JPA類(例如reloadWithProperties)附加靜態方法。這個方法創建一個新的數據源,然後在JNDI中反彈。

+0

我正在嘗試做類似的事情。你能否提供更多關於我可以接觸到的細節。我的插件似乎在db配置執行後運行。 –

+0

@ dom-farr我已經添加了關於鉤子的評論。 –

+0

謝謝。這將工作。雖然我現在已經找到了那些討厭的變種,所以我可以擴大原始配置。 –

5

關鍵是使用ConfigFactory創建一個新的Config條目。這個新的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())); 
    } 
} 
+0

太棒了!正是我正在尋找的。 – Chaitanya

相關問題