tags:

views:

338

answers:

5

We're developing a big J2ee e-sales solution. It's got a lot of integrations: CMS, ERP, Mail server etc. All these systems are divided into test and production environments.

We need to deploy our application to our test servers with test configuration and when deployed to our production servers it should use the production configuration. How do we make our application select the correct properties?

The thing we've tried so far is this:

All our property files contain test properties and production properties

test.mvxapi.server = SERV100TS
test.mvxapi.username = user
test.mvxapi.password = password
test.mvxapi.port = 6006
test.mvxapi.cono = 600

mvxapi.server = SERV10001
mvxapi.username = user
mvxapi.password = password
mvxapi.port = 6001
mvxapi.cono = 100

The Util that reads these properties has a switch: isTest() which prefixes the key with "test."

public String getProperty(String property)
{
    return properties.getProperty(prefix + "" + property);
}

The switch is set by another property which is created by our build server. When the .EAR is built the script for our production servers injects (input to build.xml) "isProduction=true" into system.properties.

<propertyfile file="${buildDir}/system.properties">
  <entry  key="isProduction" value="${systemType}"/>
 </propertyfile>

I'm not sure this is the best way to do it. If for some reason "isProduction=false" is committed wrongly to our production environment all hell is loose.

I've read people have properties locally on the server. But we really don't want to have files spread around. We have cluster of production servers. Making sure every server has the right property file doesn't seem fail-safe

A: 

I can't say if this is the best way, however, what we do is include a client and server jar which houses the properties accordingly. We then include those jars in the EAR file. So during our build process we include the appropriate (QA, TEST, PROD) jars for the environment in which we are deploying to.

The downside is we have to manage three sets of environment jars and the build team has to be careful not to deploy the incorrect one. In fact, it has happened once that we had a PROD jar deployed to our QA environment and QA data was getting put into production....yes that sucked and was a major mess to clean up.

I will be watching this discussion because I often wonder how we can make this process better/safer. Great Post +1

northpole
+1  A: 

You deploy an EAR? Then put the properties needed in JNDI.

Thorbjørn Ravn Andersen
that could work. But it seems like a lot of manual work to keep all these properties in sync across alot of servers. How would you version control them?
Tommy
Depends on which server you use. I believe e.g. JBoss allows for configuring JNDI entries through deploying archives similar to EAR and WAR, which allows you to use the same procedure as for your main application. Otherwise script it, and version the script.
Thorbjørn Ravn Andersen
Additionally if you build seperate versions for testing and production, you are deploying untested code in production, as you have tested a different build.
Thorbjørn Ravn Andersen
A: 

In a previous J2EE project, we've been doing exactly that. The build process (an ant script) put together the right config files, added them to a certain jar which was then put into the EAR file for production environments, test, training, QA, etc.

The file name of the EAR file contained the name of the target environment, so it was basically impossible to deploy a file to the wrong environment. If we built for target 156p2 (factory 156, production env. 2), this would be part of the file name of the EAR file and ant would include config_156p2.xml. If the target was incorrect, the EAR file's name would be wrong and as a last failsafe the guy who deployed it would notice.

The build file had to contain this: one ant target to start the build for each environment which would set a property that told ant which config file to include.

The only difference between the EAR files would then be the config files. Everything else was identical. There is a possibility, of course, that someone might have written a wrong value to a config file for a certain environment. However, in practice this never happened in several years, even with some pretty junior developers and about fifteen target environments (different test, QA, training and production servers in different countries).

Robert Petermeier
+1  A: 

What you want to avoid is having the config file inside the EAR, the problem with this is that you need different EAR's for different environments, and also, changing the config file requires a rebuild.

Rather deploy the same EAR to every server but configure each server with a different URL resource. iow, add a JNDI url resource to all the servers you deploy to that point to the config file for that resource. If you have read only SVN access to your repo then create the config files on the svn repo, or any repo you can access via a URL. The cool thing here is that all your configuration is centralised and thus managing them is easy.

What I've done (by customising with spring) is make that jndi url resource optional. So, if it's there, the app will use it, if not, it won't. The app starts up whether it's there or not. That way, even when running with no jdni resource available, the app still works (development environment for example).

Michael Wiles
I'll look into the JNDI url resource. Reading the config directly from SVN sounds good. If i'm understanding this correctly? How do you handle changes to the config? Just restart the EAR?You wrote that you had some kind of failover. Whats the fallback? config-files in the EAR?
Tommy
The fall back is config files in the EAR. To explicate further... this is the order config files are loaded1. default config file 2. config file named via a hostname (hostname specific, also in the EAR). So you can easily configure apps running on different nodes, e.g so each developer can configure his environment.3. config file looked up via jndiThe last value loaded is the one it uses and 2 and 3 are optional.To refresh the config, once it's changed, we just restarted the EAR (because we're using spring, the config files are read when the application context is created at startup).
Michael Wiles
A: 

We have 3 folders for this purpose in our projects, each one contains configuration files (filenames are the same between the folders):

  • personal: contains paths to test db, server, etc
  • test: contains paths to the servers shared with my colleagues
  • production: contains... well you guessed

When I build my project I add the suited profile to Intellij Idea project build, in the desidered module, this basically means that i am adding a different folder to the project structure, but because filenames are the same what changes are only profile properties.

Alberto Zaccagni