Our development and deployment approach follows the steps:
- During development, templatize the property values (i.e., a property file entry would look like server.host=@server.host@) which needs to change, be it across environments or servers.
- Maintain environment specific property files - one '.env' file per environment (i.e., for env1 -> server.host=172.24.1.2 and for env2 -> server.host=172.24.1.3 etc.)
- During the build, replace each templatized value with an actual value from the specific environment file. Then deploy the generated property files.
This works for templatizing property values across multiple environments, but not for multiple servers within the same environment. What we used initially was we had a .env file per server per environment, e.g., test.server1.env, test.server2.env etc. The problem with this approach is that 98% of the values in both these server specific env files are same. So, when something changes, we had to go and modify all these redundant server-specific files which was painful as well as error-prone.
So, we have now decided to use 2 levels of env files. For an environment, there will be 1 env file which will contain all the templatization keys that is common to all load balancing servers across the test environment. There will be another server specific environment file which will contain JUST the templatization keys that are server specific. Then we use ANT to synthesize the final property file from both these env files on a server by server basis.
To illustrate by an example...
Let's say we have a property file which needs replacement called app.properties.template
log.level=@level@ log.file=@filepath@ throttle=5 host=@host.ip@ port=@host.port@In the above, I have 5 property key/value pairs. One of which is static (throttle). Another 2 (log.level, log.file) are supposed to be same for all servers in an environment and final two (host, port) which are supposed to be different for each server in an environment.
We have the replace.env which replaces takes care of the properties which are same across all servers.
level=DEBUG filepath=/usr/home/tomcat/app/logs/
Then, we have the server specific replacement env files:
replace.env.server1
host.ip=172.24.1.1 host.port=61009replace.env.server2
host.ip=172.24.1.2 host.port=61010
And, finally the ANT build.xml
If we run ant change -Denv=server1, the app.properties gets generated, which looks like
log.level=DEBUG log.file=/usr/home/tomcat/app/logs/ throttle=5 host=172.24.1.1 port=61009
And, if we run ant change -Denv=server2, the app.properties gets generated, which looks like
log.level=DEBUG log.file=/usr/home/tomcat/app/logs/ throttle=5 host=172.24.1.2 port=61010
What is happening here is that the copy task finds all files ending in .template and uses the filterset task to replace the templatization tokens. We are using 2 filtersfile, the first one being the env file which contains environment specific templatization keys and the second one being the server specific templatization keys within the environment.
This approach helps to keep the environment files more modular and clean.
With ant 1.8.1 , there are some jar files available to process the values from nested property file.
ReplyDeleteUsing the jar helps to use nested properties file.
In the above ex:
${${env.file}.${env}}
So rather than maintaining 3 different prorpeties file we can have only properties file... one for enviroment and other for server...
Vijay.C.K