<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Suryachoudhury's Weblog</title>
	<atom:link href="http://suryachoudhury.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://suryachoudhury.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Wed, 23 Dec 2009 21:36:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='suryachoudhury.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Suryachoudhury's Weblog</title>
		<link>http://suryachoudhury.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://suryachoudhury.wordpress.com/osd.xml" title="Suryachoudhury&#039;s Weblog" />
	<atom:link rel='hub' href='http://suryachoudhury.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Conditionally Defining Spring Beans</title>
		<link>http://suryachoudhury.wordpress.com/2009/12/23/conditionally-defining-spring-beans/</link>
		<comments>http://suryachoudhury.wordpress.com/2009/12/23/conditionally-defining-spring-beans/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 21:05:01 +0000</pubDate>
		<dc:creator>Surya Choudhury</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://suryachoudhury.wordpress.com/?p=29</guid>
		<description><![CDATA[One feature missing from Spring framework that I would find handy is the ability to define a bean based on an EL (Expressional Language) or a particular property is defined. So without further suspense here is what a conditionally defined bean looks like: &#60;beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:if="http://mycompany.com/springbeans/condition"     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    http://mycompany.com/springbeans/condition http://mycompany.com/springbeans/condition/condition.xsd"&#62; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=suryachoudhury.wordpress.com&amp;blog=2710699&amp;post=29&amp;subd=suryachoudhury&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One feature missing from Spring framework that I would find handy is the ability to define a bean based on an EL (Expressional Language) or a particular property is defined.</p>
<p>So without further suspense here is what a conditionally defined bean looks like:</p>
<pre>
</pre>
<pre>&lt;beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <strong>xmlns:if="http://mycompany.com/springbeans/condition"</strong>
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
   <strong>http://mycompany.com/springbeans/condition http://mycompany.com/springbeans/condition/condition.xsd</strong>"&gt;</pre>
<p>&lt;!&#8211; Please note the name space &#8220;<strong>xmlns:if=&#8221;http://mycompany.com/springbeans/condition</strong>&#8221; and schema<br />
location &#8220;*<a rel="nofollow" href="http://sungardhe.com/springbeans/condition">http://mycompany.com/springbeans/condition</a><a rel="nofollow" href="http://sungardhe.com/springbeans/condition/condition.xsd*">http://mycompany.com/springbeans/condition/condition.xsd*</a>&#8220;<br />
&#8211;&gt;<br />
<em><strong><span style="color:#003366;">&lt;if:condition</span></strong></em><br />
<em><strong>test=&#8221;${(jms.server.type == &#8216;activemq&#8217;) &amp;amp;&amp;amp; (isMessageBrokerEnabled == true)}&#8221;</strong></em><br />
<em><strong>varnames=&#8221;jms.server.type,isMessageBrokerEnabled&#8221;</strong></em><br />
<em><strong>src=&#8221;META-INF/bootstrap.properties&#8221; &gt;</strong></em><br />
<em><strong> </strong></em></p>
<pre><em><strong><span style="color:#003366;">&lt;bean id="apacheMQConnectionFactory"&gt;</span></strong></em></pre>
<pre><em><strong><span style="color:#003366;">    &lt;property name="brokerURL" value="tcp://e3_cloud_senxex.mycompany.com:61616"/&gt;</span></strong></em></pre>
<pre><em><strong><span style="color:#003366;">    &lt;property name="userName" value="admin"/&gt;</span></strong></em></pre>
<pre><em><strong><span style="color:#003366;">    &lt;property name="password" value="xVkE2iPpk9"/&gt;</span></strong></em></pre>
<pre><em><strong><span style="color:#003366;">&lt;/bean&gt;
</span></strong></em></pre>
<pre><em><strong><span style="color:#003366;">&lt;/if:condition&gt;</span>
</strong></em></pre>
<p>What the example above does? Is a bean defination defining a Sping JMS connector for Apache ActiveMQ. If the EL condition is *true* then the bean will be instantiated.</p>
<p>The property jms.server.type and isMessageBrokerEnabled is defined in the property file bootstrap.properties</p>
<p>Of course instead of conditional logic we could split the bean definitions up into multiple files and connect them together for different tasks &#8211; e.g. construct one application context for Apache ActiveMQ and Sun Message Broker that includes an xml file for a JMS provider specific configurations,  but if you only have a small number of different beans then it may not be worth constructing multiple application contexts at build time. Even for products that comesup with multiple JMS connector support, where installer are provided to the product sells/service team for customer side installation. In such senerio we need to make installation process simple and we don’t want to individual build for each customer.</p>
<p>So given I&#8217;m restricting myself to xml configuration I thought I&#8217;de try out the<a href="http://static.springframework.org/spring/docs/2.0.x/reference/extensible-xml.html"> Spring 2.0 Extensible XML Authoring API</a>. This API allows you to add your own attributes to bean definitions or allow you to define beans using your own XML syntax. Using this API I got close to what I wanted, with a few limitations.</p>
<p>As per the Extensible XML Authoring API the infrastructure to set up the above is as follows:</p>
<h3><span style="color:#993300;"> Step 1) Authoring The Schema</span></h3>
<h4><span style="color:#008000;">com/mycompany/product/spring/condition.xsd</span></h4>
<pre><span style="color:#003366;"><strong>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
</strong></span>

<span style="color:#003366;"><strong>&lt;xsd:schema xmlns="http://mycompany.com/springbeans/condition"</strong></span>

<span style="color:#003366;"><strong>            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
</strong></span>

<span style="color:#003366;"><strong>            xmlns:beans="http://www.springframework.org/schema/beans"
</strong></span>

<span style="color:#003366;"><strong>            targetNamespace="http://mycompany.com/springbeans/condition"
</strong></span>

<span style="color:#003366;"><strong>            elementFormDefault="qualified"</strong></span>

<span style="color:#003366;"><strong>            attributeFormDefault="unqualified"&gt;  </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>&lt;xsd:import namespace="http://www.w3.org/XML/1998/namespace" /&gt;  </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>&lt;xsd:annotation&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>&lt;xsd:documentation&gt;&lt;![CDATA[ </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       Defines the configuration elements for My Comany Spring Framework's conditional bean creation. </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       Limitations: </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       1. The spring-beans-2.0.xsd forces you to define a &lt;if:condition/&gt;
</strong></span>

<span style="color:#003366;"><strong>          for single beans - you cannot put a &lt;if:condition/&gt; block around a group of beans. </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       2. The spring-beans-2.0.xsd prevents you from defining two beans with the same name </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>          in the same XML file, even if different &lt;if:condition/&gt; conditions guarantee only</strong></span>
<span style="color:#003366;"><strong>          one of the definitions will be in force at any given time. ]]&gt;
&lt;/xsd:documentation&gt; </strong></span>
<span style="color:#003366;"><strong>&lt;/xsd:annotation&gt;</strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>&lt;xsd:element name="condition"&gt;</strong></span>
<span style="color:#003366;"><strong>   &lt;xsd:complexType&gt;
      &lt;xsd:sequence&gt;
        &lt;xsd:any minOccurs="0" /&gt;
      &lt;/xsd:sequence&gt; </strong></span>
<span style="color:#003366;"><strong>      &lt;xsd:attribute name="test" type="xsd:string" use="required"&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:annotation&gt;
</strong></span>

<span style="color:#003366;"><strong>          &lt;xsd:documentation&gt;&lt;![CDATA[
</strong></span>

<span style="color:#003366;"><strong>                   Define the param value that need to tested as a condition for bean creation. </strong></span>
<span style="color:#003366;"><strong>                   For example if '${myCondition}=true' then the following child bean will be instantiated.
                                   ]]&gt;&lt;/xsd:documentation&gt; </strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:annotation&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:attribute&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:attribute name="varnames" type="xsd:string" use="optional"&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:annotation&gt;</strong></span>

<span style="color:#003366;"><strong>           &lt;xsd:documentation&gt;&lt;![CDATA[ </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>               Define the param name that need to be tested against the set of property source provided in the src attribute.</strong></span>
<span style="color:#003366;"><strong>                  ]]&gt;&lt;/xsd:documentation&gt; </strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:annotation&gt;</strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:attribute&gt; </strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:attribute name="src" type="xsd:string" use="required"&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:annotation&gt;</strong></span>
<span style="color:#003366;"><strong>       &lt;xsd:documentation&gt;&lt;![CDATA[ </strong></span>
<span style="color:#003366;"><strong>              Define the property file/xml from which the test param can be loaded.</strong></span>
<span style="color:#003366;"><strong>                  ]]&gt;&lt;/xsd:documentation&gt; </strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:annotation&gt;</strong></span>
<span style="color:#003366;"><strong>       &lt;/xsd:attribute&gt; </strong></span>
<span style="color:#003366;"><strong>&lt;/xsd:complexType&gt; </strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>&lt;/xsd:element&gt;</strong></span>
<span style="color:#003366;"> </span>
<span style="color:#003366;"><strong>&lt;/xsd:schema&gt;</strong></span>

<span style="color:#993300;">
</span>

<span style="color:#993300;">
</span>
<h2><span style="color:#993300;">Step 2) Coding a NamespaceHandler</span></h2>

<span style="color:#993300;">
</span>

<span style="color:#003366;"><strong>package com.mycompany.product.spring;</strong></span>

<span style="color:#003366;"><strong>import org.springframework.beans.factory.xml.NamespaceHandlerSupport; </strong></span>

<span style="color:#003366;"><strong>/** </strong></span>

<span style="color:#003366;"><strong>* @author &lt;A href="mailto:snc_43@yahoo.com"&gt;Surya Choudhury&lt;/A&gt;</strong></span>

<span style="color:#003366;"><strong>* </strong></span>

<span style="color:#003366;"><strong>*/</strong></span>

<span style="color:#003366;"><strong>public class ConditionalBeanNamespaceHandler extends NamespaceHandlerSupport {
</strong></span>
<span style="color:#003366;"><strong> </strong></span>
<span style="color:#003366;"><strong>/* (non-Javadoc) </strong></span>

<span style="color:#003366;"><strong>* @see org.springframework.beans.factory.xml.NamespaceHandler#init() </strong></span>

<span style="color:#003366;"><strong>*/ </strong></span>

<span style="color:#003366;"><strong>@Override </strong></span>

<span style="color:#003366;"><strong>  public void init() { </strong></span>

<span style="color:#003366;"><strong>      super.registerBeanDefinitionParser("condition", new ConditionalBeanDefinitionParser());</strong></span>

<span style="color:#003366;"><strong>   }</strong></span>

<span style="color:#003366;"><strong>}</strong></span>

<strong>
</strong>

<strong>
</strong>
<h2><span style="color:#993300;">Step 3) Coding a BeanDefinitionParser</span></h2>
</pre>
<pre><span style="color:#000080;">
</span>
<span style="color:#000080;">package com.mycompany.product.spring;</span>
<span style="color:#000080;">import java.util.Properties;</span>
<span style="color:#000080;">import org.apache.commons.jexl.Expression;</span>
<span style="color:#000080;">import org.apache.commons.jexl.ExpressionFactory;</span>
<span style="color:#000080;">import org.apache.commons.jexl.JexlContext;</span>
<span style="color:#000080;">import org.apache.commons.jexl.JexlHelper;</span>
<span style="color:#000080;">import org.apache.commons.lang.StringUtils;</span>
<span style="color:#000080;">import org.apache.commons.logging.Log;</span>
<span style="color:#000080;">import org.apache.commons.logging.LogFactory;</span>
<span style="color:#000080;">import org.springframework.beans.factory.config.BeanDefinition;</span>
<span style="color:#000080;">import org.springframework.beans.factory.config.BeanDefinitionHolder;</span>
<span style="color:#000080;">import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;</span>
<span style="color:#000080;">import org.springframework.beans.factory.xml.BeanDefinitionParser;</span>
<span style="color:#000080;">import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;</span>
<span style="color:#000080;">import org.springframework.beans.factory.xml.ParserContext;</span>
<span style="color:#000080;">import org.springframework.core.io.Resource;</span>
<span style="color:#000080;">import org.springframework.util.xml.DomUtils;</span>
<span style="color:#000080;">import org.w3c.dom.Element;
</span>
<span style="color:#000080;"> </span>
<span style="color:#000080;">/**</span>
<span style="color:#000080;">* @author &lt;A href="mailto:snc_43@yahoo.com"&gt;Surya Choudhury&lt;/A&gt;</span>
<span style="color:#000080;">*</span>
<span style="color:#000080;">*/</span>
<span style="color:#000080;">public class ConditionalBeanDefinitionParser implements BeanDefinitionParser {</span>
<span style="color:#000080;">       private final Log cLog = LogFactory.getLog(ConditionalBeanDefinitionParser.class);</span>
<span style="color:#000080;">       private Properties config;</span>
<span style="color:#000080;">
</span>
<span style="color:#000080;">      /** Default placeholder prefix: "${" */</span>
<span style="color:#000080;">      public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";</span>
<span style="color:#000080;">      /** Default placeholder suffix: "}" */</span>
<span style="color:#000080;">      public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";</span>
<span style="color:#000080;">
</span>
<span style="color:#000080;">      public ConditionalBeanDefinitionParser() {</span>
<span style="color:#000080;">            config = new Properties();</span>
<span style="color:#000080;">      }</span>
<span style="color:#000080;">
</span>
<span style="color:#000080;">      /**</span>
<span style="color:#000080;">      * Parse the "condition" element and check the mandatory "test" attribute. If</span>
<span style="color:#000080;">      * the provided resources or the system property named by test is null/empty/false</span>
<span style="color:#000080;">      * (i.e. not defined) then return null, which is the same as not defining the bean.</span>
<span style="color:#000080;">      */</span>
<span style="color:#000080;">      public BeanDefinition parse(Element element, ParserContext parserContext) {</span>
<span style="color:#000080;">             try{</span>
<span style="color:#000080;">               if (DomUtils.nodeNameEquals(element, "condition")) {</span>
<span style="color:#000080;">                  String test = element.getAttribute("test");</span>
<span style="color:#000080;">                  String src = element.getAttribute("src");</span>
<span style="color:#000080;">                  String varnames = element.getAttribute("varnames"); </span>
<span style="color:#000080;"> </span>
<span style="color:#000080;">                  // Check the src attribute is not empty.</span>
<span style="color:#000080;">                   if(StringUtils.isNotEmpty(src)){</span>
<span style="color:#000080;">                      Resource resource = parserContext.getReaderContext().getResourceLoader().getResource(src.trim());</span>
<span style="color:#000080;">                      config.load(resource.getInputStream());</span>
<span style="color:#000080;">                   }else{</span>
<span style="color:#000080;">                      throw new IllegalArgumentException("src attribute not set.");</span>
<span style="color:#000080;">                   } </span>
<span style="color:#000080;">                  // Check if the varnames is not empty/null</span>
<span style="color:#000080;">                  if(StringUtils.isNotEmpty(test) &amp;&amp; StringUtils.isNotEmpty(varnames) &amp;&amp; StringUtils.isNotBlank(varnames)){</span>
<span style="color:#000080;">                     String expression = test.substring(</span>
<span style="color:#000080;">                                DEFAULT_PLACEHOLDER_PREFIX.length(),</span>
<span style="color:#000080;">                                test.length() - DEFAULT_PLACEHOLDER_SUFFIX.length()).trim();
</span>
<span style="color:#000080;">                     String[] vars = varnames.split(",");</span>
<span style="color:#000080;">                     JexlContext jc = JexlHelper.createContext();</span>
<span style="color:#000080;">                     for(String varname: vars){</span>
<span style="color:#000080;">                       varname = varname.trim();</span>
<span style="color:#000080;">                       jc.getVars().put(varname, config.get(varname));</span>
<span style="color:#000080;">                     }</span>
<span style="color:#000080;">                     Expression e = ExpressionFactory.createExpression(expression);</span>
<span style="color:#000080;">                     Object result = e.evaluate(jc);  </span>
<span style="color:#000080;">                     if( (null != result)){</span>
<span style="color:#000080;">                       if(result.toString().equalsIgnoreCase("true")){</span>
<span style="color:#000080;">                          Element beanElement = DomUtils.getChildElementByTagName(element, "bean");</span>
<span style="color:#000080;">                          return parseAndRegisterBean(beanElement, parserContext);</span>
<span style="color:#000080;">                       }else if(result.toString().equalsIgnoreCase("false")){</span>
<span style="color:#000080;">                          return null;</span>
<span style="color:#000080;">                       }else if ( StringUtils.isNotEmpty(getProperty(test))) {</span>
<span style="color:#000080;">                          Element beanElement = DomUtils.getChildElementByTagName(element, "bean");</span>
<span style="color:#000080;">                          return parseAndRegisterBean(beanElement, parserContext);</span>
<span style="color:#000080;">                       }else{</span>
<span style="color:#000080;">                          cLog.warn("Condition bean creation did not happen as test or src attribute is not set.");</span>
<span style="color:#000080;">                       }</span>
<span style="color:#000080;">                  }</span>
<span style="color:#000080;">             }</span>
<span style="color:#000080;">            // Else proceed with non-empty/NULL/Boolean value check</span>
<span style="color:#000080;">            else{</span>
<span style="color:#000080;">               if ( StringUtils.isNotEmpty(getProperty(test))) {</span>
<span style="color:#000080;">                  Element beanElement = DomUtils.getChildElementByTagName(element, "bean");</span>
<span style="color:#000080;">                  return parseAndRegisterBean(beanElement, parserContext);</span>
<span style="color:#000080;">                }else{</span>
<span style="color:#000080;">                  cLog.warn("Condition bean creation did not happen as test or src attribute is not set.");</span>
<span style="color:#000080;">                }</span>
<span style="color:#000080;">           }</span>
<span style="color:#000080;">        }</span>
<span style="color:#000080;">     }catch (Exception e) {</span>
<span style="color:#000080;">         cLog.error("Fail to load condition bean.", e);</span>
<span style="color:#000080;">     }</span>
<span style="color:#000080;">        return null;</span>
<span style="color:#000080;">    } </span>
<span style="color:#000080;">
</span>
<span style="color:#000080;">    /**</span>
<span style="color:#000080;">     * Get the value of a named resource/system property (it may not be defined).</span>
<span style="color:#000080;">     *</span>
<span style="color:#000080;">     * @param strVal The name of a system property. The property may</span>
<span style="color:#000080;">     * optionally be surrounded in Ant/EL-style brackets. e.g. "${propertyname}" </span>
<span style="color:#000080;">     *</span>
<span style="color:#000080;">     * @return</span>
<span style="color:#000080;">     */</span>
<span style="color:#000080;">      private String getProperty(String strVal) {</span>
<span style="color:#000080;">              cLog.info(strVal);</span>
<span style="color:#000080;">              if (StringUtils.isEmpty(strVal)) {</span>
<span style="color:#000080;">                  return null;</span>
<span style="color:#000080;">              } </span>
<span style="color:#000080;">              String returnValue = null;</span>
<span style="color:#000080;">              if (strVal.startsWith(DEFAULT_PLACEHOLDER_PREFIX) &amp;&amp; strVal.endsWith(DEFAULT_PLACEHOLDER_SUFFIX)) {</span>
<span style="color:#000080;">                  returnValue = config.getProperty(</span>
<span style="color:#000080;">                        strVal.substring(DEFAULT_PLACEHOLDER_PREFIX.length(),</span>
<span style="color:#000080;">                        strVal.length() - DEFAULT_PLACEHOLDER_SUFFIX.length()).trim());</span>
<span style="color:#000080;">                  if(null == returnValue){</span>
<span style="color:#000080;">                      returnValue = System.getProperty(</span>
<span style="color:#000080;">                              strVal.substring(DEFAULT_PLACEHOLDER_PREFIX.length(),</span>
<span style="color:#000080;">                              strVal.length() - DEFAULT_PLACEHOLDER_SUFFIX.length()));</span>
<span style="color:#000080;">                   }</span>
<span style="color:#000080;">                   if( StringUtils.isNotEmpty(returnValue)){</span>
<span style="color:#000080;">                      if(returnValue.trim().equalsIgnoreCase("false"))</span>
<span style="color:#000080;">                          returnValue = null;</span>
<span style="color:#000080;">                       }</span>
<span style="color:#000080;">                       if(cLog.isDebugEnabled()){</span>
<span style="color:#000080;">                           cLog.debug("Returned : "+System.getProperty(</span>
<span style="color:#000080;">                                     strVal.substring(DEFAULT_PLACEHOLDER_PREFIX.length(),</span>
<span style="color:#000080;">                                     strVal.length() - DEFAULT_PLACEHOLDER_SUFFIX.length())));</span>
<span style="color:#000080;">                        }</span>
<span style="color:#000080;">                        return returnValue;</span>
<span style="color:#000080;">                     }else{</span>
<span style="color:#000080;">                        return System.getProperty(strVal);</span>
<span style="color:#000080;">                    }</span>
<span style="color:#000080;">                } </span>
<span style="color:#000080;">
</span>
<span style="color:#000080;">         private BeanDefinition parseAndRegisterBean(Element element, ParserContext parserContext) {</span>
<span style="color:#000080;">                BeanDefinitionParserDelegate delegate = parserContext.getDelegate();</span>
<span style="color:#000080;">                BeanDefinitionHolder holder = delegate.parseBeanDefinitionElement(element);</span>
<span style="color:#000080;">                BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry()); </span>
<span style="color:#000080;">                return holder.getBeanDefinition();</span>
<span style="color:#000080;">        }</span></pre>
<p><span style="color:#000080;"> }</span><br />
<span style="color:#000080;"> </span></p>
<h3><strong><span style="color:#993300;">Step 4) Register the Handler and the Schema</span></strong></h3>
<h4><span style="color:#008000;"><strong>META-INF/spring.handlers</strong></span></h4>
<pre><span style="color:#000080;">http\://mycompany.com/springbeans/condition=com.mycompany.product.spring.ConditionalBeanNamespaceHandler

</span><span style="color:#008000;"><strong>META-INF/spring.schemas</strong></span>
<span style="color:#000080;">http\://mycompany.com/springbeans/condition/condition.xsd=com/mycompany/product/spring/condition.xsd</span></pre>
<p>Special note for developing in Tomcat: Spring looks for META-INF/spring.handlers and META-INF/spring.schemas on the classpath. webapp/META-INF is not on the Tomcat classpath, so you need to put these files inside a JAR or (hack warning) in the webapp/WEB-INF/classes/META-INF directory.</p>
<p><span style="color:#003366;">Other conditional operators like</span>: &lt;, &lt;=, &gt;, &gt;=, ==, !=, ||, &amp;&amp; etc. are also legal expression</p>
<p><span style="color:#003366;"><strong>NOTE: As there are few restriction that is been add by the spring-bean-2.0.xsd, so while defining character like &lt;, &gt;, ||, &amp;&amp; it is better to use its html/ASCII code, for example a &#8216;&amp;&amp;&#8217; condition can be noted as &#8216;&amp;&amp;&#8217; similarly &#8216;&gt;&#8217; as &#8216;&gt;&#8217; and &#8216;&lt;&#8217; as &#8216;&lt;&#8217; etc.</strong></span></p>
<p><span style="color:#003366;">The attribute varnames is an optional attribute, but when an expression is subjected for evaluation (as in above examples) all the variable names are required to be passed with comma separated as varnames value.</span></p>
<p><span style="color:#003366;"><strong>Limitations</strong></span></p>
<p><span style="color:#003366;">A common way of configuring an application with property replacement is to use a</span><span style="color:#003366;"> </span>PropertyPlaceholderConfigurer<span style="color:#003366;"> </span><span style="color:#003366;">bean. Unfortunately this is a two-pass process: the first pass parses a bean definition, the second pass does property replacement. The Extensible Authoring XML API only allows you to interact with the first pass, so that means we are limited to things that are defined at bean definiton time, such as system properties or provide a properties file to the &#8220;src&#8221; attribute [The same parser context loader's ResourceLoader will be used to load the src properties file]</span></p>
<p><span style="color:#003366;"><strong>Note: Both test and src are mandatory attributes for &lt;if:condition/&gt;</strong></span></p>
<p><span style="color:#003366;">The spring-beans-2.0.xsd forces you to define a &lt;if:condition/&gt; for single beans &#8211; you cannot put a &lt;if:condition/&gt; block around a group of beans.</span></p>
<p><span style="color:#003366;">The spring-beans-2.0.xsd prevents you from defining two beans with the same name in the same XML file, even if different &lt;if:condition/&gt; conditions guarantee only one of the definitions will be in force at any given time.</span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/suryachoudhury.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/suryachoudhury.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/suryachoudhury.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=suryachoudhury.wordpress.com&amp;blog=2710699&amp;post=29&amp;subd=suryachoudhury&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://suryachoudhury.wordpress.com/2009/12/23/conditionally-defining-spring-beans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e457bd79197bb845b8deb7435f7a6717?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">suryachoudhury</media:title>
		</media:content>
	</item>
		<item>
		<title>Building Highly Scalable and more rich content, reliable sites</title>
		<link>http://suryachoudhury.wordpress.com/2009/03/16/building-highly-scalable/</link>
		<comments>http://suryachoudhury.wordpress.com/2009/03/16/building-highly-scalable/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 10:37:45 +0000</pubDate>
		<dc:creator>Surya Choudhury</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://suryachoudhury.wordpress.com/?p=3</guid>
		<description><![CDATA[Well, when we talk about building more reliable and massive websites with more than petabytes of rich content data&#8230;  and that to be served as a SaaS model and part of business solution suite (I mean a product). That means you are turning on towards Brobdingnagian market. Well this a business where you need to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=suryachoudhury.wordpress.com&amp;blog=2710699&amp;post=3&amp;subd=suryachoudhury&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span>Well, when we talk about building more reliable and massive websites with more than <span>petabytes</span> of rich content data&#8230;  and that to be served as a <span>SaaS</span> model and part of business solution suite (I mean a product).</span></p>
<p><span>That means you are turning on towards Brobdingnagian market. Well this a business where you need to more accurate. Apart from the various parameter that are considered while building a site, I &#8216;ll narrate two major parameters and design/solutions, that are considered while developing a rich site.</span></p>
<p>1. Scalability.</p>
<p>2. Performance.</p>
<p><strong>Scalability</strong><span>:    Any software/application design needs to <span>pre</span>-evaluate and scale the industries they are targeting for. Lets take discuss the same with an example.</span></p>
<p>In early 2004, the <strong><span><span>Facebook</span>.com</span></strong><span> site was mostly used by Harvard students as a glorified on-line yearbook. One can imagine that the entire storage requirements and query load on the database could be handled by a single beefy server. Fast forward to 2008 where just the <span>Facebook</span> application related page views are about </span><strong>14 billion a month</strong> (which translates to over<strong> 5,000 page views per second</strong><span>, each of which will require multiple <span>backend</span> queries to satisfy). Besides query load with its attendant </span><strong><span><span>IOPS</span>, CPU and memory cost</span></strong><span> there&#8217;s also storage capacity to consider. Today <span>Facebook</span> stores </span><strong><span>40 billion physical files to represent about 10 billion photos which will cover a <span>petabyte</span> of storage</span></strong><span>. Even though the actual photo files are likely not in a relational database, their <span>metadata</span> such as identifiers and locations still would require a few terabytes of storage to represent these photos in the database. Do you think the original database used by <span>Facebook</span> had terabytes of storage available just to store photo <span>metadata</span>?</span></p>
<p><span>At some point during the development of <span>Facebook</span>, they reached the physical capacity of their database server. The question then was whether to scale vertically by buying a more expensive, beefier server with more RAM, CPU horsepower, disk I/O and storage capacity or to spread their data out across multiple relatively cheap database servers. In general if your service has lots of rapidly changing data (i.e. lots of writes) or is sporadically queried by lots of users in a way which causes your working set not to fit in memory (i.e. lots of reads leading to lots of page faults and disk seeks) then your primary bottleneck will likely be I/O. This is typically the case with social media sites like <span>Facebook</span>, <span>LinkedIn</span>, <span>Blogger</span>, <span>MySpace</span> and even <span>Flickr</span>. In such cases, it is either prohibitively expensive or physically impossible to purchase a single server to handle the load on the site. In such situations <span>sharding</span> the database provides excellent bang for the buck with regards to cost savings relative to the increased complexity of the system.</span></p>
<p><span>Now that we have an understanding of when and why one would shard a database, the next step is to consider how one would actually partition the data into individual shards. There are a number of options and their individual <span>tradeoffs</span> presented below – <span>Pseudocode</span> / Joins</span></p>
<h3><span>How <span>Sharding</span> Changes your Application</span></h3>
<p><span>In a well designed application, the primary change <span>sharding</span> adds to the core application code is that instead of code such as</span></p>
<blockquote>
<pre class="code"><span style="color:green;"><span>//string <span>connectionString</span> = @"Driver={<span>MySQL</span>};SERVER=<span>dbserver</span>;DATABASE=<span>CustomerDB</span>;"; &lt;-- should be in web.<span>config</span></span></span><span style="color:blue;">string </span><span><span>connectionString</span> = </span><span style="color:#2b91af;"><span><span>ConfigurationSettings</span></span></span><span>.<span>AppSettings</span>[</span><span style="color:#a31515;"><span>"<span>ConnectionInfo</span>"</span></span>];<span style="color:#2b91af;"><span><span>OdbcConnection</span> </span></span>conn = <span style="color:blue;">new </span><span style="color:#2b91af;"><span><span>OdbcConnection</span></span></span><span>(<span>connectionString</span>);</span>conn.Open();

<span style="color:#2b91af;"><span><span>OdbcCommand</span> </span></span>cmd = <span style="color:blue;">new </span><span style="color:#2b91af;"><span><span>OdbcCommand</span></span></span>(<span style="color:#a31515;"><span>"SELECT Name, Address FROM Customers WHERE <span>CustomerID</span>= ?"</span></span>, conn);<span style="color:#2b91af;">OdbcParameter </span><span><span>param</span> = <span>cmd</span>.Parameters.Add(</span><span style="color:#a31515;"><span>"@<span>CustomerID</span>"</span></span>, <span style="color:#2b91af;"><span><span>OdbcType</span></span></span>.Int);<span><span>param</span>.Value = <span>customerId</span>;</span><span style="color:#2b91af;">OdbcDataReader </span><span>reader = <span>cmd</span>.<span>ExecuteReader</span>();</span></pre>
</blockquote>
<p>the actual connection information about the database to connect to depends on the data we are trying to store or access. So you&#8217;d have the following instead</p>
<blockquote>
<pre class="code"><span style="background-color:yellow;"><span style="color:blue;">string </span><span><span>connectionString</span> = <span>GetDatabaseFor</span>(<span>customerId</span>);   </span></span><span style="color:#2b91af;"><span><span>OdbcConnection</span> </span></span>conn = <span style="color:blue;">new </span><span style="color:#2b91af;"><span><span>OdbcConnection</span></span></span><span>(<span>connectionString</span>);</span>conn.Open();

<span style="color:#2b91af;"><span><span>OdbcCommand</span> </span></span>cmd = <span style="color:blue;">new </span><span style="color:#2b91af;"><span><span>OdbcCommand</span></span></span>(<span style="color:#a31515;"><span>"SELECT Name, Address FROM Customers WHERE <span>CustomerID</span>= ?"</span></span>, conn);<span style="color:#2b91af;">OdbcParameter </span><span><span>param</span> = <span>cmd</span>.Parameters.Add(</span><span style="color:#a31515;"><span>"@<span>CustomerID</span>"</span></span>, <span style="color:#2b91af;"><span><span>OdbcType</span></span></span>.Int);<span><span>param</span>.Value = <span>customerId</span>;</span><span style="color:#2b91af;">OdbcDataReader </span><span>reader = <span>cmd</span>.<span>ExecuteReader</span>();</span></pre>
</blockquote>
<p>the assumption here being that the <code><span><span>GetDatabaseFor</span>()</span></code><span> method knows how to map a customer ID to a physical database location. For the most part everything else should remain the same unless the application uses <span>sharding</span> as a way to <span>parallelize</span> queries.</span></p>
<h3><span>A Look at a Some Common <span>Sharding</span> Schemes</span></h3>
<p><span>There are a number of different schemes one could use to decide how to break up an application database into multiple smaller <span>DBs</span>. Below are four of the most popular schemes used by various large scale Web applications today.</span></p>
<ol>
<li><span style="text-decoration:underline;">Vertical Partitioning:</span><span> A simple way to segment your application database is to move tables related to specific features to their own server. For example, placing user profile information on one database server, friend lists on another and a third for user generated content like photos and <span>blogs</span>. The key benefit of this approach is that is straightforward to implement and has low impact to the application as a whole. The main problem with this approach is that if the site experiences additional growth then it may be necessary to further shard a feature specific database across multiple servers (e.g. handling <span>metadata</span> queries for 10 billion photos by 140 million users may be more than a single server can handle).</span></li>
<li><span style="text-decoration:underline;">Range Based Partitioning:</span><span> In situations where the entire data set for a single feature or table still needs to be further subdivided across multiple servers, it is important to ensure that the data is split up in a predictable manner. One approach to ensuring this predictability is to split the data based on values ranges that occur within each entity. For example, splitting up sales transactions by what year they were created or assigning users to servers based on the first digit of their zip code. The main problem with this approach is that if the value whose range is used for partitioning isn&#8217;t chosen carefully then the <span>sharding</span> scheme leads to unbalanced servers. In the previous example, splitting up transactions by date means that the server with the current year gets a disproportionate amount of read and write traffic. Similarly partitioning users based on their zip code assumes that your user base will be evenly distributed across the different zip codes which fails to account for situations where your application is popular in a particular region and the fact that human populations vary across different zip codes.</span></li>
<li><span style="text-decoration:underline;">Key or Hash Based Partitioning:</span> This is often a synonym for user based partitioning for Web 2.0 sites. With this approach, each entity has a value that can be used as input into a hash function whose output is used to determine which database server to use. A simplistic example is to consider if you have ten database servers and your user IDs were a numeric value that was incremented by 1 each time a new user is added. In this example, the hash function could be perform a <a href="http://en.wikipedia.org/wiki/Modulo_operation">modulo operation</a> on the user ID with the number ten and then pick a database server based on the remainder value. This approach should ensure a uniform allocation of data to each server. The key problem with this approach is that it effectively fixes your number of database servers since adding new servers means changing the hash function which without downtime is like being asked to change the tires on a moving car.</li>
<li><span style="text-decoration:underline;">Directory Based Partitioning:</span><span> A loosely couples approach to this problem is to create a <span>lookup</span> service which knows your current partitioning scheme and abstracts it away from the database access code. This means the </span><code><span><span>GetDatabaseFor</span>()</span></code><span> method actually hits a web service or a database which actually stores/returns the mapping between each entity key and the database server it resides on. This loosely coupled approach means you can perform tasks like adding servers to the database pool or change your partitioning scheme without having to impact your application. Consider the previous example where there are ten servers and the hash function is a modulo operation. Let&#8217;s say we want to add five database servers to the pool without incurring downtime. We can keep the existing hash function, add these servers to the pool and then run a script that copies data from the ten existing servers to the five new servers based on a new hash function implemented by performing the modulo operation on user IDs using the new server count of fifteen. Once the data is copied over (although this is tricky since users are always updating their data) the <span>lookup</span> service can change to using the new hash function without any of the calling applications being any wiser that their database pool just grew 50% and the database they went to for accessing John Doe&#8217;s pictures five minutes ago is different from the one they are accessing now.</span></li>
</ol>
<h3><span>Problems Common to all <span>Sharding</span> Schemes</span></h3>
<p><span>Once a database has been <span>sharded</span>, new constraints are placed on the operations that can be performed on the database. These constraints primarily center around the fact that operations across multiple tables or multiple rows in the same table no longer will run on the same server. Below are some of the constraints and additional complexities introduced by <span>sharding</span></span></p>
<ul>
<li><span>Joins and <span>Denormalization</span> – Prior to <span>sharding</span> a database, any queries that require joins on multiple tables execute on a single server. Once a database has been <span>sharded</span> across multiple servers, it is often not feasible to perform joins that span database shards due to performance constraints since data has to be compiled from multiple servers and the additional complexity of performing such cross-server.A common workaround is to <span>denormalize</span> the database so that queries that previously required joins can be performed from a single table. For example, consider a photo site which has a database which contains a </span><code>user_info</code> table and a <code>photos</code><span> table. Comments a user has left on photos are stored in the photos table and reference the user&#8217;s ID as a foreign key. So when you go to the user&#8217;s profile it takes a join of the user_info and photos tables to show the user&#8217;s recent comments.  After <span>sharding</span> the database, it now takes querying two database servers to perform an operation that used to require hitting only one server. This performance hit can be avoided by <span>denormalizing</span> the database. In this case, a user&#8217;s comments on photos could be stored in the same table or server as their user_info AND the photos table also has a copy of the comment. That way rendering a photo page and showing its comments only has to hit the server with the photos table while rendering a user profile page with their recent comments only has to hit the server with the user_info table.Of course, the service now has to deal with all the perils of <span>denormalization</span> such as data inconsistency (e.g. user deletes a comment and the operation is successful against the user_info DB server but fails against the photos DB server because it was just rebooted after a critical security patch).</span></li>
<li><span>Referential integrity – As you can imagine if there&#8217;s a bad story around performing cross-shard queries it is even worse trying to enforce data integrity constraints such as foreign keys in a <span>sharded</span> database. Most relational database management systems do not support foreign keys across databases on different database servers. This means that applications that require referential integrity often have to enforce it in application code and run regular <span>SQL</span> jobs to clean up dangling references once they move to using database shards.Dealing with data inconsistency issues due to <span>denormalization</span> and lack of referential integrity can become a significant development cost to the service.</span></li>
<li><span><span>Rebalancing</span> </span><strong>(Updated 1/21/2009)</strong><span> – In some cases, the <span>sharding</span> scheme chosen for a database has to be changed. This could happen because the <span>sharding</span> scheme was improperly chosen (e.g. partitioning users by zip code) or the application outgrows the database even after being <span>sharded</span> (e.g. too many requests being handled by the DB shard dedicated to photos so more database servers are needed for handling photos). In such cases, the database shards will have to be rebalanced which means the partitioning scheme changed AND all existing data moved to new locations. Doing this without incurring down time is extremely difficult and not supported by any off-the-shelf today. Using a scheme like directory based partitioning does make <span>rebalancing</span> a more palatable experience at the cost of increasing the complexity of the system and creating a new single point of failure (i.e. the <span>lookup</span> service/database).</span></li>
</ul>
<p><span>Well&#8230; I&#8217;m just snoozing at my <span>keyboad</span>&#8230; We will talk about building high <span>prerformance</span> rich content architecture in my next post&#8230;</span></p>
<p><span>Just a hint for you that when we do have streaming response (that mean video, music, files etc) it is better to have a chip level <span>multi</span> threaded server like <span>lighttpd</span> wrapped around the content <span>managment</span> system <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/suryachoudhury.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/suryachoudhury.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/suryachoudhury.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=suryachoudhury.wordpress.com&amp;blog=2710699&amp;post=3&amp;subd=suryachoudhury&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://suryachoudhury.wordpress.com/2009/03/16/building-highly-scalable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e457bd79197bb845b8deb7435f7a6717?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">suryachoudhury</media:title>
		</media:content>
	</item>
	</channel>
</rss>
