2010/01/27

How to provide settings to your web a...

How to provide settings to your web applications


Overview

An app shouldn't need to know what environment its going to be deployed into, however the maker of the app should know about the resources that are going to be required.  So there are [at least] two good ways to do this.  Store all the settings for an application in the database and then the only thing that is required is the database configuration for each environment -- which is usually handled by the container.  Or you can have all of these settings in in property files with an extension that indicates which environment (DEV, PRD, etc.) that the setting is for.

The down side to the database is that anyone can change a setting that they think is only for their app and it will change all of the apps that are using it.  The downside of having the settings in a property file for each app is if the resource does need to change it requires the change to be made in all of the applications.  It is similar to the battle between deploying dependent libs where they are accessible to everyone all at once or deploying the dependent libraries with each application.


Details
The rest of this article will focus on the later approach.

So we have decided that we want all of the settings in property files.  And we want each container to know what environment it is in.  Then we will have a library that will pull the correct setting for the property depending on the environment.  This library will be reused between all applications as part of the common framework.

Lets look at this in more detail...

We want the container to know what environment its in.  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), we need to create our newly styled property file.  Oh but what does that look like?

Create a file myApp.properties and it would contain this:

# First we have LCL (Local)
theOtherServerLCL=192.168.1.1

theUserIdLCL=dev_user

# Now for DEV (Dev :-))
theOtherServerDEV=192.168.1.1

theUserIdDEV=dev_user

# Now for FT1 (Test)
theOtherServerFT1=16.32.64.128

theUserIdFT1=test_user

# Now for PRD (Production)
theOtherServerPRD=10.20.40.80

theUserIdPRD=prod_user

Now for more information about the available environments.  This really depends on the system architecture for the application or department but probably something like this:

LCL, DEV, FT1, FT2, TRN, PRD

Note that local (LCL) should probably have the same settings as DEV, but we can do additional optimizations like not combining resources so the build time is less, but by the time it goes to DEV it is the integrated build.  We'll talk more about those another time.

Next is the important decision of how to split up property files, but we'll also leave this for a different post.


Summary
So in summary, the ServerEnv needs to be in every server so that each server can indicate to the applications what environment it's in.  Each application should include all of the settings that it will need for all environments stored in its property files.  One build can go to any environment, and each environment doesn't need to know about all the possible configuration settings needed for the applications.


Happy Coding!






No comments: