Deployment – Spring – Overriding properties when deploying in a multi-server environment

I found myself wanting to have certain property values in my Spring projects differ based on what server the app is being deployed.

For example your company has dev, test, qa, prod boxes etc… But there are certain properties in your app such as default db username and passwords, database name, thread pool configurations, etc… that are specific to the server or environment where the app is running.

The technique presented in this tutorial allows you to place all common and default properties in a properties file and provide overrides based on the hostname of the server where the app is running.

For example you can have a application.myDevBoxHostName.properties that will allow you to load property values associated to your own local environment versus a application.myCompany.com.properties that will load the right set of properties in production servers. Also you can have simply application.properties to load all properties that are common or with default values for all environments that do not override properties

This tutorial is available for download with svn:

svn checkout http://raulrajatutorials.googlecode.com/svn/trunk/ raulrajatutorials-read-only

Comments in the code itself should be self-explanatory if you already have some java + spring experience

And now to the point.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <!--
    This service allows loading of properties based on hostname supporting default values in application.properties and allowing
    other servers to override the default property values in their own server specific application._HOST_NAME_.properties
    -->
    <bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesMode" value="1"/>
        <property name="locations">
            <list>
                <value>/WEB-INF/conf/application.properties</value>
                <!--
                    In deployments servers: /WEB-INF/conf/application._HOST_NAME_.properties will override properties in application.properties.
                    based on the hostname in the deployed server
                -->
                <bean class="com.raulraja.util.deployment.CompositeStringResourceProvider" factory-method="getReplacedResource">
                    <constructor-arg>
                        <bean class="com.raulraja.util.deployment.impl.SpringInjectedServletContextProviderImpl" />
                    </constructor-arg>
                    <constructor-arg value="/WEB-INF/conf/application._HOST_NAME_.properties"/>
                </bean>
            </list>
        </property>
        <property name="ignoreResourceNotFound" value="true"/>
    </bean>
 
    <!-- This is a sample service that will get properties injected and will display its values on initialization -->
    <bean id="sampleService" class="com.raulraja.util.deployment.impl.SampleServiceImpl" init-method="init">
        <property name="firstProperty" value="${first.property.placeholder}" />
        <property name="secondProperty" value="${second.property.placeholder}" />
    </bean>
 
</beans>

application.properties

#In this file live all common properties and default property values for all servers
first.property.placeholder=this value was declared in application.properties
second.property.placeholder=this value was declared in application.properties

application.yourHostNameHere.properties

# This file contains properties overriden for the host name were the app is being deployed
second.property.placeholder=this value is overriden in a specific server config declared in application.properties

CompositeStringResourceProvider.java

package com.raulraja.util.deployment;
 
import org.apache.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.context.support.ServletContextResource;
 
import java.net.UnknownHostException;
import java.net.InetAddress;
 
/**
 * A service that provides a resource based on the host name
 */
public class CompositeStringResourceProvider {
 
    private final static Logger log = Logger.getLogger(CompositeStringResourceProvider.class);
 
    private final static String HOSTNAME_PLACEHOLDER = "_HOST_NAME_";
 
	/**
	 * This method is invoked by the container at startup
	 * @param servletContextProvider a servlet context provider
	 * @param baseResource the base resource
	 * @return the resource assigned to the current running server
	 * @throws UnknownHostException if the host is unknown
	 */
    public static Resource getReplacedResource(ServletContextProvider servletContextProvider, String baseResource) throws UnknownHostException {
        InetAddress localhost = InetAddress.getLocalHost();
        baseResource = baseResource.replaceAll(HOSTNAME_PLACEHOLDER, localhost.getHostName());
        Resource resource = null;
        if (servletContextProvider.getServletContext() != null) {
            resource = new ServletContextResource(servletContextProvider.getServletContext(), baseResource);
            if (resource.exists()) {
                log.debug("Loading override for common properties: " + resource.getFilename());
            }
        } else {
            resource = new ClassPathResource(baseResource);
        }
 
        return resource;
    }
 
}

ServletContextProvider.java

package com.raulraja.util.deployment;
 
import javax.servlet.ServletContext;
 
/**
 * Provides a servlet context
 */
public interface ServletContextProvider {
 
	/**
	 * @return the servlet context
	 */
    ServletContext getServletContext();
 
}

SpringInjectedServletContextProviderImpl.java

package com.raulraja.util.deployment.impl;
 
 
import com.raulraja.util.deployment.ServletContextProvider;
import org.springframework.web.context.ServletContextAware;
 
import javax.servlet.ServletContext;
 
/**
 * Spring based impl of the ServletContextProvider
 */
public class SpringInjectedServletContextProviderImpl implements ServletContextProvider, ServletContextAware {
 
	/**
	 * the servlet context
	 */
    private ServletContext servletContext;
 
	/**
	 * @return the servlet context
	 */
    public ServletContext getServletContext() {
        return servletContext;
    }
 
	/**
	 * sets the servlet context, invoked by the container at startup since this service implements ServletContextAware 
	 * @param servletContext the servlet context
	 */
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
}

SampleServiceImpl.java

package com.raulraja.util.deployment.impl;
 
import org.apache.log4j.Logger;
 
/**
 * Demonstrates how values of properties are injected based on a specific hostname config
 */
public class SampleServiceImpl {
 
	private final static Logger log = Logger.getLogger(SampleServiceImpl.class);
 
	/**
	 * the first prperty
	 */
	private String firstProperty;
 
	/**
	 * the second property
	 */
	private String secondProperty;
 
	/**
	 * service initialization method
	 */
	public void init() {
		log.debug("first property: " + firstProperty);
		log.debug("second property: " + secondProperty);
	}
 
	/**
	 * sets the first property
	 * @param firstProperty the first property
	 */
	public void setFirstProperty(String firstProperty) {
		this.firstProperty = firstProperty;
	}
 
	/**
	 * sets the second property
	 * @param secondProperty the second property
	 */
	public void setSecondProperty(String secondProperty) {
		this.secondProperty = secondProperty;
	}
}

Now notice that my local machine hostname is raul-raja-martinezs-macbook.local

Before application.raul-raja-martinezs-macbook.local.properties existed:

06/13 17:49:52 WARN org.springframework.beans.factory.config.PropertyPlaceholderConfigurer – Could not load properties from ServletContext resource [/WEB-INF/conf/application.raul-raja-martinezs-macbook.local.properties]: Could not open ServletContext resource [/WEB-INF/conf/application.raul-raja-martinezs-macbook.local.properties]
06/13 18:00:47 DEBUG com.raulraja.util.deployment.impl.SampleServiceImpl – first property: this value was declared in application.properties
06/13 18:00:47 DEBUG com.raulraja.util.deployment.impl.SampleServiceImpl - second property: this value was declared in application.properties

After application.raul-raja-martinezs-macbook.local.properties existed:

06/13 18:03:52 DEBUG com.raulraja.util.deployment.CompositeStringResourceProvider – Loading override for common properties: application.raul-raja-martinezs-macbook.local.properties
06/13 18:03:52 DEBUG com.raulraja.util.deployment.impl.SampleServiceImpl – first property: this value was declared in application.properties
06/13 18:03:52 DEBUG com.raulraja.util.deployment.impl.SampleServiceImpl – second property: this value is overriden in a specific server config declared in application.properties

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • TwitThis
  • email
  • FriendFeed
  • PDF
  • Slashdot

This post is tagged , ,

don't '

Leave a Reply

Comments may be held for moderation, please do not repost. I reserve the right to remove any inappropriate or off-topic comments. If you plan on sharing helpful code, please pass it through Postable first. Want other to know who you are? Register a Gravatar.





Sponsored Links

Categories

Pages

juice141
insurance158
gardens47
jewelers93
bestyoucanfind.info
heart146
james29
lyrics167
industries92
google142
lafayette9
kitchen229
lyrics120
jesus90
italian248
lyrics1
afreeocx.com
guide24
manhattan166
green201
information113
frank168
lyrics160
lyrics190
family142
kofflerboats.com
hitachi214
festival182
forest102
jamaica25
hotel86
executive74
guide23
flavor28
grant172
hockey221
free-microsofts.com
lyrics239
thesagamore.com
failed120
hockey220
healthbenefitsdepot.com
generic67
exchange72
fever194
island235
games21
italy249
manual188
management155
excellpressurewashers.com
library131
gibson97
grill212
marble210
flights35
hotel150
manitoba168
manual186
found137
finance231
house216
install128
institute139
lyric61
garden44
katie169
guitar51
festival181
hotels171
house189
franchise158
columbiatn.com
insurance150
guitar58
illinois22
louisville24
little204
festival189
height163
lyric67
guitar48
lyrics152
lyric48
lacrosse6
hotel154
georgia80
marine233
fitness19
cam.com
hospital62
hunter243
magazine103
floyd73
living210
sex-teen.org
lyrics46
honda22
honey36
mmgins.com
hotel142
ithaca3
lyrics202
lyrics142
management154
lyrics50
hunting247
harold105
creeksidepreserve.com
logic235
forum124
letter111
industrial90
lyrics31
gainesville242
hotel138
island224
heaters152
lyrics171
lyric69
marysvilleohio.org
gauge53
laboratories3
estate2
fields205
infant100
hairstyles77
indian72
james35
ireland214
maine125
houston231
malta148
jones128
fireplace241
honey36
rustyiron.com
finder236
germany90
jessica88
magnum119
fruit195
lyrics235
inurl204
guild36
lyrics37
kennel188
groups248
handbags91
freedom177
jeremy71
lyric81
furnace215
falls129
installing131
manufacturing203
lauderdale58
hotels176
major128
estate25
kenwood198
guitar47
hyderabad7
lyrics129
latex53
fabric103
lonsberry.com
lyrics147
maine123
sunyacc.edu
james27
veostingray.com
landing17
gallery12
lyrics231
madden90
furniture217
lyrics179
fountain146
little197
indian70
lounge27
lyrics121
keygen206
kevin201
import41
foster135
happy95
history199
jones124
kitten231
furniture236
manor170
language22
festival186
flash24
guitar43
lyrics44
homes8
hawaii119
hotel108
madden90
knight236
goneglobal35.com
florist65
myispfinder.org
lyric81
estate12
grand166
estate40
lyrics126
guitars67
fiber195
jumper148
limited160
hamilton85
female171
hospital67
instant132
estate6
glasses123
legal90
level116
pdc.org
estate18
india67
gallery13
kingdom217
florida59
katrina172
lyric76
linux183
football89
ingredients119
gymnastics73
houston229
humidifier241
naral.org
flying75
jewelry102
marine235
internet191
hotel133
hospital54
finder236
katrina172
listing193
lodge228
johnny110
mygibline.com
lyrics231
exhaust83
india54
little196
fuelmaker.com
lyrics163
harrison108
europe51
leather84
luggage33
gallery1
london242
lyrics67
magnum119
italy249
gallery3
lyrics9
london246
24fusion.info
hawaii118
lyric69
great186
thunderwear.com
market243
lyrics200
guide23
james27
linux179
houston222
example60
louisiana21
living211
maison127
californiaduihelp.com
fisher8
lyrics42
horses52
horse46
genesis68
indianapolis82
headphones123
lyrics201
forum123
local219
jelly60
malaysia144
fender177
lyric65
factory116
nomino.ca
greensboro206
express93
humidifier241
lights156
exercise76
girls104
jewish103
honda17
pulaskicountyassessor.net
lyric78
lyric75
harley103
group234
houses217
hockey219
lynch39
machine76
honda31
island229
gymnastics73
harvard114
katie168
infant100
lyrics207
language33
financialhack.com
login238
garcia35
manufacturer202
banana1015.com