Centralized management of DB connections in Java
For compliance reasons, my organization wants to set our database connection settings from properties / XML config files and to a central registry - ideally pooled across multiple physical machines to avoid a single point of failure.
I was considering using JNDI to achieve this, but I didn't really have a lot of experience using it. Has anyone got any experience trying to do something like this? Or any better ideas on how this can be achieved?
I must add that our applications are standalone and do not run in any J2EE container, so any container-specific connection management methods may not be particularly useful.
a source to share
It might be easier to follow the XML / file properties approach, but use some centralized configuration management system to manage the content of those files.
Presumably, if you need to consider centralizing things like data source configuration, you already have something in place (CFEngine, puppet, chef, rdist, ...) to manage operating system configuration files - so why not just don't use what?
a source to share
This might be a good start:
HashMap<String,String> dsNames = new HashMap<String,String>();
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
System.setProperty(Context.PROVIDER_URL, "file:/home/user/tmp");
InitialContext ic = new InitialContext();
dsNames.put("yourDataSourceName", "jdbc/your_jndi_name");
// Construct BasicDataSource reference
Reference ref = new Reference("javax.sql.DataSource",
"org.apache.commons.dbcp.BasicDataSourceFactory", null);
ref.add(new StringRefAddr("driverClassName", "theDriver"));
ref.add(new StringRefAddr("url","theDBURL"));
ref.add(new StringRefAddr("username", "obvious"));
ref.add(new StringRefAddr("password", "obvious"));
ref.add(new StringRefAddr("maxActive", "10"));
ref.add(new StringRefAddr("maxIdle", "3"));
ref.add(new StringRefAddr("initialSize", "3"));
ref.add(new StringRefAddr("maxWait", "5"));
ic.rebind("jdbc/your_jndi_name", ref);
//And to get a reference to your data source anywhere else in your program:
InitialContext ic2 = new InitialContext();
DataSource myDS = (DataSource) ic2.lookup(dsNames.get(dsName));
Now, as you can see, I am using a concatenated factory connection, but you can replace it according to your needs. Also, the initial factory context is FSContext, which means the JNDI name will look up in normal filesystem, the Context factory URL should be available, but I've never used it. Most of the classes used are in the javax.naming package.
Hope it helps.
What regulation are you trying to comply with?
One thing you can do is depend on the datasource being exposed through JNDI. This will mean, however, that your connection settings are in your datasource configuration site.
I doubt you need to "go horizontally" with your database connection settings. Is there a specific reason why you think having the settings in one place could put your apps at risk?
a source to share