如何在运行时更改Play 2 Framework DB配置?

Joh*_*ann 5 database configuration playframework playframework-2.0

我们正在使用Play 2.1.1及其内置的JPA集成(JPA.em()等).

  • 我们如何动态更改db.pass属性?从Play 2.1开始,Play.application().configuration()似乎是不可变的.(或者我们至少不知道变异者)
  • 如果我们能够更改db.pass,我们如何重新加载数据库配置,以便JPA.em()使用新密码返回一个EntityManager?

我们要避免的是必须使用EntityManagerFactory重新创建EntityManager.我们希望继续让Play在JPA助手类中管理它.

背景

系统具有用于本地运行的默认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" 
Run Code Online (Sandbox Code Playgroud)

应用程序接收此数据,然后重新创建Hibernate SessionFactory.我们的新Play应用程序将需要执行类似的操作.

dom*_*arr 6

关键是使用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()));
    }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ann 3

为了回答我自己的问题,首先我们通过使用以下内容重写 Configuration.onLoadConfig 解决了在运行时更新不可变配置的问题:

  1. 如果配置表明 Production.level 是 PROD
  2. 从 stdin 读取密码
  3. 通过将旧配置转换为映射并使用 ConfigFactory.parseMap 构建新配置以及新参数来创建新配置
  4. 返回 super.onLoadConfig

但是,这仍然没有解决重新加载数据库配置的问题。最后,我的同事创建了一个Play!该插件本质上是一些 JPA 类的副本,并具有使用配置属性映射重新加载的附加功能。

更新

“挂钩”是插件添加到 JPA 类的附加静态方法(例如 reloadWithProperties)。该方法创建一个新的数据源,然后在 JNDI 中反弹。