Thursday, September 15, 2011

Spring Context Configuration and Deployment

I think as an application designer/developer when you are making decisions regarding configuration, It is critically important to think about deployment. I have had my share deployment woes early on, I think that is what made me a firm believer in making deployment task to be as routine as possible to limit the developer's role to bare minimum. In one of the application I work on, We moved the application deployment configuration to data base and applied the configuration using JMX Mbeans as application starts up in a fail fast mode.

Deployment
Here are some things that I learned that would make for a smooth deployment

  • Keep the application configuration during deployment as simple as possible
  • If you don't do that, There will be a lot of hand holding in an enterprise environment where deployment tasks are handled by administrators with little knowledge of (code and application function)
  • I am firm believer in building an artifact (ear or war) using a build tool, There are plenty of build tools available Jenkins, Bamboo , Cruise Control to name a few
  • There should be one and only one deployment artifact (ear or war) that should be preferably available as a download to deployment team to deploy it on either (Quality/Performance/Production) environment
  • Only one deployment artifact means, If you property use files that differ for each environment then that needs to be taken into account during development
  • For example, We had a problem where we needed to configure a JMS Message broker, Web Service that were connected to different sources (IP Address, Channel name, Q name) in different deployment environments (dev, qa, prod etc) 

I am going in reverse with deployment as being first just to bring out the nuances in deployment. I think one of key aspect of application design/development is the configuration that fits various deployment environments (i.e dev, qa, prod). 


Application Configuration
In a typical enterprise java environment there is some kind of application specific config during deployment. I am going to keep it simple for this blog and just provide a template on how one can solve problem like these.  Let's take a look at a web application with spring integration that communicates with a JMS Message broker, It needs to communicate with Test or Prod JMS Message broker based on the deployment environment. I have listed config files that are needed to deploy this application
  • applicationContext.xml  (Core spring context file with service layer beans)
  • jmsBrokerContext.xml (Spring Integration config for JMS Q)
  • messagebroker_qa.properties (Test message broker properties)
  • messagebroker_prod.properties (Production message broker properties)
I am listing a typical Message Broker configuration, To configure this application to communicate with appropriate Message Broker we could create property files for each environment (i.e. dev, qa or prod). 
  1. mqconn.hostName=dns name of the host
  2. mqconn.port=some port
  3. mqconn.queueManager=q manager
  4. mqconn.channel=q channel
  5. mqconn.baseQueueName.qname=queue name
Once property files are created for each environment, We could then pass a environment variable as JVM argument as defined below.
  • -Dserver_env=qa  (pass JVM argument for test server)
  • -Dserver_env=prod (pass JVM argument for prod server)
Then we could use the property place holder to inject the properties for the given server environment. As the spring container boots up It will substitute (qa for ${server_env}) for qa environment and (messagebroker_prod.properties) in production environment

<context:property-placeholder location="classpath:messagebroker_${server_env}.properties"/>

<bean id="connectionFactoryMQ" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="${mqconn.hostName}" />
<property name="port" value="${mqconn.port}" />
<property name="queueManager" value="${mqconn.queueManager}" />
<property name="channel" value="${mqconn.channel}" />
<property name="transportType" value="${mqconn.transportType}" />
</bean>

This is one way same deployment artifact could used to do deploy it in environment we choose, But all this starts during the application design/development itself. 





No comments:

Post a Comment