2010/02/18

How to provide settings to your applications part two

How to provide settings to your applications
part two
using your database



This is a second look at providing access to settings.  For the original please see http://gcruscoe.blogspot.com/2010/01/how-to-provide-settings-to-your-web.html

Overview

Please read the original article and then come back.  I'll wait, I promise.

Okay, great, glad you're back.  We are now going to supplement the previously described procedure to make the system more robust.  In order to do so we will need to look at what drawbacks there are to the method and how we can overcome them.  The description here is going to describe using a database for this approach although with a little imagination, we could come up with many different ways to get these settings.


Details
The rest of this article will focus on the setting up application servers, applications, and databases to handle settings that can change in different environments.  There are many aspects of this that will stay outside the scope of this article, like setting up the databases, proper naming conventions, etc.

So after our last look into property files, we have decided not to hard code the settings into the applications, and not to make a build specific to a particular environment.  But we still need all of the information in the application when it is built.  So what happens when a new environment is setup or an existing one changes?  This will require changing the properties files and redeploying the archive to all of the machines.  There has got to be a better way we must all be thinking right now.  And of course now we now that putting these settings in the database can offer us many benefits.  Most importantly all we need to do is change the settings in the database and the app will automatically get these new changes.  No deployment necessary.  It does has the drawback on requiring a database, but if the application already has that requirement then this is a non issue.  If it is an issue then there are plenty of other ways this can be handled.  A JNDI look up to an LDAP server, a web service call, etc.

For now we are going to focus on setting up our application to use the database.


Lets look at this in more detail...

Because you can setup a datasource at the container level, we have to question whether we even need the aforementioned, ServerEnv variable at all.  Each application server is setup to talk to a database in its environment (DEV, TEST, PROD, etc.) -- so why do we even need a setting?  You might not.  However there are situations where different types of servers may talk to the same database so in this case you will still need the ServerEnv variable.  We want the container to know what environment its in just in case.  The implementation of this is app/web server dependent but in general it will be something along the lines of edit the server.xml for your container or domain and add a system property ServerEnv pointing to the appropriate Environment.

e.g.
<jvm-options>-DServerEnv=DEV</jvm-options>

Okay now that that's set (and the app server is restarted), what else do we need?  We need a way to talk to the database -- again this is out of scope but we are going to assume there is a datasource setup for the app server and our application will be able to talk to it without knowing where it came from (this is of course a very common and highly recommended way to set up a system).

So our application needs at least one piece of information to be deployed with it -- the application name.  You can expand on what information is required as needed for security but we'll keep it simple here.  So the application will have a small property file that will contain its name and for fun you may want to add a version number.

When the application wants to get its settings, it will get them from the database that is linked up with the (or one of the) data source(s).  Okay so then the application gets all the properties using the getProperties(filter) library command that is included in every new application.  This only needs to be written once and everyone gets to benefit. 

What goes into the filter?
  • app name
  • version
  • environment

So the database has everything it needs to find properties.  Of course it can be normalized or just a string concated together, but the idea is that each key contains

appname.version.environment.propertyname = value

and you get all the properties from the database and then in the application you have your hashmap of just

propertyname = value

So now the archive can be deployed anywhere -- even in environments that were not thought of when the application was made.  All that is necessary is to create the appropriate settings in the database for each application.


Summary
So in summary, the ServerEnv needs to be in every server so that each server can fine tune what information it needs from the database.  The application only needs to know its name and version.  One build can go to any environment, even if it doesn't exist yet.  Each database connection is setup for the app server so the app doesn't even need to know about that.


Happy Coding!






No comments: