We are using Play 2.1.1 and its built-in JPA integration (JPA.em() etc).
- How can we dynamically change the db.pass property? Play.application().configuration() seems to be immutable as of Play 2.1. (or we're at least not aware of the mutators)
- If we are able to change db.pass, how can we reload the DB configuration so that JPA.em() returns an EntityManager using the new password?
What we are trying to avoid is having to recreate the EntityManager using EntityManagerFactory. We want to continue to let Play manage that in the JPA helper class.
Background
The system has a default DB configuration for running locally. When deployed to a server, the DB password is dynamically set on the running application using the following script:
#!/bin/bash
stty -echo
read -p "Password: " PASS
stty echo
curl -k https://127.0.0.1:8443/someUrl/pwd --data "password=$PASS"
The application receives this data and then recreates the Hibernate SessionFactory. Our new Play app will be required to do something similar.
To answer my own question, at first we solved the problem of updating the immutable configuration at runtime by overriding Configuration.onLoadConfig with the following:
However, this still didn't address that the problem of reloading the DB configuration. In the end, my colleague created a Play! plugin which essentially a copy of some JPA classes with the added capability of being reloaded with a Map of configuration properties.
Update
The "hook" is the additional static method which the plugin adds to the JPA class (e.g. reloadWithProperties). This method creates a new data source which is then rebound in JNDI.
The key is to use the ConfigFactory to create a new Config entry. This new Config contains an entry for password with the value coming from your http call to your password service.
A new Configuration is created using the new Config, which in turn falls back to the original Config from the original Configuration.
Basically the new password entry supersedes the original.
It sound long winded when you say it, but the code is pretty readable.