Tuesday, March 22, 2011

Accessing Websphere Variables at runtime.

I'm using Redis and I had a security need to keep the production configuration values hidden.  However, I wanted to allow other developers to run against test with minimal configuration.

I decided that I wanted to be able to read the Webpshere Variables that are configured on the WAS server through code.

I started with some code I found on IBM's site to get the data, but added a simple null check to make it return null if the code is not running on a server.

I had to add a reference to com.ibm.jaxws.thinclient_7.0.0.jar (this was the recommended reference by RAD) this .jar is needed for the AdminService class.

A few quirks
1. if the server is not running (when unit tests run) you have to handle a default value, this method will return null.
2. If the property does not exist on the server it returns in ${propertyname}. 
3. Any changes to the values on the server require a restart before they can be used by the application.

I handled this with a properties file that will be used when running unit tests or on my local server, and the values from Websphere variables will only be used in production.  I structured it in a way that the production values take precedence over the test values.

ResourceBundle settings=ResourceBundle.getBundle("twitter");

// if the values are not set then this will return ${variablename}
String redisServer = expandVariable("REDIS_SERVER");
if (redisServer == null || redisServer.startsWith("${")) {
                redisServer = settings.getString("redis.server");

String redisPassword = expandVariable("REDIS_PASSWORD");
if( redisPassword == null || redisPassword.startsWith("${")) {
                redisPassword = settings.getString("redis.password");

String redisPort = expandVariable("REDIS_PORT");
if( redisPort == null || redisPort.startsWith("${")) {
                redisPort = settings.getString("redis.port");

I still recommend clearing out the test values when deploying to production, this will ensure that if the production property has not been set and the server restarted that the application is not accidentally pointing at test.  I'd rather have an error that a production application pointing at test.