<?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>My experiments with technology</title>
	<atom:link href="http://technicalmumbojumbo.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://technicalmumbojumbo.wordpress.com</link>
	<description>My oasis in the desert of Project Management</description>
	<lastBuildDate>Fri, 06 Nov 2009 14:23:56 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='technicalmumbojumbo.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/cd146318c2530b520bd60885c82c109d?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>My experiments with technology</title>
		<link>http://technicalmumbojumbo.wordpress.com</link>
	</image>
			<item>
		<title>Web Application Performance Tuning Tips</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/10/24/web-application-performance-tuning-tips/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/10/24/web-application-performance-tuning-tips/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 14:41:22 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[performance]]></category>
		<category><![CDATA[performance tuning]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=194</guid>
		<description><![CDATA[In my role as a Java Technical Architect, I am forced to wear different thinking hats. Some times I am a Solution Architect, Subject Matter Expert on some technology and the last few days I have been wearing the hat of performance tuning expert. Today I am going to pen down some thoughts around what a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=194&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In my role as a <strong><em>Java</em></strong> <strong><em>Technical Architect</em><span style="font-weight:normal;">, I am forced to wear different thinking hats. Some times I am a Solution Architect, Subject Matter Expert on some technology and the last few days I have been wearing the hat of <em>performance tuning expert</em>. Today I am going to pen down some thoughts around what a person should focus on once he or she is by design or default selected to tune an application.</span></strong></p>
<p><strong><span style="font-weight:normal;"><span id="more-194"></span></span></strong></p>
<blockquote><p><span style="font-weight:normal;"><strong>Rule No. 1: <span style="text-decoration:underline;">Focus on data and not on people.</span></strong></span></p></blockquote>
<p><span style="font-weight:normal;">The first thing that happens whenever there is a performance issue is that there is a lot of people talking about the issue and adding their colored perception and inferences without supporting evidence. Such people will come in all shapes and sizes, project managers, delivery owners, programmers and any one who wants to feel important by putting down his or her opinion. <em>It is your job to separate out the noise from the sound</em>. Do not let these people&#8217;s opinions cloud your perspective. The first thing to do is respectfully enquire if anyone has taken the effort to gather any data around the performance issue. If not, start gathering the same yourself. This is the first and the most essential step in your arsenal, which you would revert to time and again to back your observations or performance improvement suggestions.</span></p>
<p>So, how do you gather data? There is a lot of sophisticated tooling like profilers and performance monitoring equipment around, however I always use my humble file logger to capture information. Here&#8217;s a sample.</p>
<pre>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:416px;width:1px;height:1px;">XXXX Some method invocation of a significant process</div>

long startTime = System.nanoTime();
XXXX Some method invocation of a significant process
long endTime = System.nanoTime();
logger.debug("Time spent in invoking significant method: " + (endTime-startTime)/1000000 + " msec.");</pre>
<p>Identify possible bottleneck areas and put in logger statements like what I have written above. Profilers will freeze, but the humble logger will always log unabated, which moves us to rule no. 2.</p>
<blockquote><p><strong><span style="font-weight:normal;"><strong>Rule No. 2: <span style="text-decoration:underline;">Focus on basics of performance tuning.</span></strong> </span></strong></p></blockquote>
<p><strong><span style="font-weight:normal;">Before jumping into the application code and theorizing on the possible areas to fix look at the obvious, check if your JVM has enough memory allocated, the CPU has enough free time, in case of database queries check out if they have been tuned. Seems the obvious choices, unfortunately projects suffer because the obvious is overlooked for the exotic. Just recently I was called because a criteria based UI search was taking a lot of time, specifically 30 to 90 seconds. After some digging it became apparent that the database procedure fetching the search results was slow and was consuming 95% of the total process time. I spoke to the PL/SQL developer and inquired what made the query slow.  His conclusion was the query was on a single table containing around 75 million records. On my pestering he asked the DBA to run statistics which apparently also tunes up the table and presto the search results appeared in 3 secs. Conclusion, <em>do not overlook the obvious</em>. </span></strong></p>
<blockquote><p><strong><span style="font-weight:normal;"><strong>Rule No. 3: <span style="text-decoration:underline;">Do performance testing on the target machine in the target environment.</span></strong></span></strong></p></blockquote>
<p>A few years ago I was asked to look into a memory leak. The target system was a Unix machine in the customer environment and all developer machines were on Windows. We spent around 2 weeks working on the developer boxes trying to replicate the memory leak issue. It never appeared. So we changed tact and got monitoring enabled on the target machine. Another week of testing and the conclusion was that Tomcat 4.1 on Unix had a memory leak. The Windows version did not have the same problem. So lesson for the day, always ensure that you do the testing on the same machine where the failure is reported.</p>
<blockquote><p><strong>Rule No. 4: <span style="text-decoration:underline;">Watch out for framework specific idiosyncrasies.</span></strong></p></blockquote>
<p>Each framework, tooling or component that you utilize in your application has its own characteristics. Typically each framework has one or a limited set of objects which hold all the configuration information. For example, JAXBContext in JAXB, SessionFactory in hibernate or EJBHome in EJBs. These are heavy objects whose creation imposes a performance penalty. Care should be taken in design to ensure that one or a limited set of objects are created thus avoiding the performance penalty.</p>
<p>One of the integration projects my organization was working on was facing some performance issues. The project used a lot of web services and concerned people were speculating that the issue was due to excess use of web services.  Although the statement was true, that was just half truth. Due to the large number of Web Services, there was a considerable marshalling and unmarshalling happening. JAXB was used for the data transformation which is not a problem except that on each and every marshalling and unmarshalling operation, a new JAXBContext was created, this was consuming @5 seconds for a single object creation, the entire operation was taking around 90 seconds. On changing the implementation to creating the JAXBContext once in the application lifetime and reusing the same object the response time was down to 3 secs. Such objects are typically threadsafe by design. It&#8217;s just up to you to know that and make a judicious decision in implementation.</p>
<blockquote><p><strong>Rule No. 5: <span style="text-decoration:underline;">Observe the performance metrics for all moving parts/components.</span></strong></p></blockquote>
<p>A web application consists of many moving parts/components, the presentation tier, integration tier, data access tier and other third-party components like document generation, bar code generator utility etc. As a performance tuning consultant you need to observe the performance characteristics of these parts under variety of business scenarios. At times a component takes time only under certain business flow. To capture this behavior load test the application and run the same scenario over and over again. This is an extremely useful technique in capturing slow forming memory leaks and also identifying or ruling out components that might have performance problems.</p>
<blockquote><p><strong>Rule No. 6: <span style="text-decoration:underline;">Remember the 80-20 principle.</span></strong></p></blockquote>
<p>Application code is written by developers of varying experience and expertise levels. This translates into poor design or non-implementation of design patterns, reusable code etc. However modern-day JVMs are robust enough not to take a performance hit or take a limited performance hit due to poor coding standards. Do not waste your time in doing static code analysis and suggesting code implementation as per standards. Remember most of the performance problems have one or two root causes. Fix these and the bottlenecks disappear. Do your 20% by identifying these problem areas and get 80% improved throughput.</p>
<p>Finally, my rules/tips are simple, obvious and will be apparent to people with common sense. However time and again in practice, I have seen these been overlooked. After all common sense is a sense not found in common people.</p>
<p>Thats all from performance tuning help desk.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/194/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=194&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/10/24/web-application-performance-tuning-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>Developing RESTful Web Services using JBoss RESTEasy</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/10/13/restful-webservices-using-jboss-resteasy-tutorial/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/10/13/restful-webservices-using-jboss-resteasy-tutorial/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 11:36:59 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[JBoss RESTEasy]]></category>
		<category><![CDATA[RESTEasy]]></category>
		<category><![CDATA[RESTful WebServices]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=183</guid>
		<description><![CDATA[Enterprise integration was and remains a key challenge in ensuring availiability of enterprise data as a single source of truth in real time manner. Over the decades number of techniques/technologies have come and gone. We have seen EAI,JMS, Web Services, SOA etc that have contended providing true enterprise integration solutions. The latest to join this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=183&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">Enterprise integration was and remains a key challenge in ensuring availiability of enterprise data as a single source of truth in real time manner. Over the decades number of techniques/technologies have come and gone. We have seen EAI,JMS, Web Services, SOA etc that have contended providing true enterprise integration solutions. The latest to join this bandwagon is REST and its implementation avatar is described as RESTful Web Services. In case you are interested in understanding what REST is and how does it compare vis-a-vis SOAP, WebServices et all refer the link(URL: http://2007.xtech.org/public/asset/attachment/76) for details. This post is going to provide a ready-to-use tutorial around how to implement RESTful WebServices using JBoss RESTEasy project.</div>
<p>Enterprise integration was and remains a key challenge in ensuring availability of enterprise data as a single source of truth in real time manner. Over the decades number of techniques/technologies have come and gone. We have seen EAI,JMS, Web Services, SOA etc that have contended providing true enterprise integration solutions. The latest to join this bandwagon is REST and its implementation avatar is described as RESTful Web Services. In case you are interested in understanding what REST is and how does it compare vis-a-vis SOAP, WebServices et all refer the <a title="RESTful WebServices SOAP Compariosn" href="http://2007.xtech.org/public/asset/attachment/76" target="_blank">link</a> for details. This post is going to provide a ready-to-use tutorial around how to implement RESTful WebServices using JBoss RESTEasy project.</p>
<p><span id="more-183"></span></p>
<div>The RESTEasy project is configurabe as a web application archive(WAR) file and is deployable in any JEE compliant servlet container. For our tutorial, I have deployed it in a Tomcat container(version 5.5). The development environment is set up using Eclipse Europa version 3.3.2 and the Sysdeo Tomcat Eclipse plugin version 3.2.1. To kick start the proceedings, create a Tomcat Project called RESTWeb in Eclipse. Specify your context name and web application root. I have named both as &#8220;/rest&#8221;. Within the project create the following folder structure RESTWeb/rest/WEB-INF/lib. Within WEB-INF folder create the web.xml file. The structure of the web.xml is as follows:</div>
<div></div>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"&gt;

&lt;display-name&gt;RESTful Web Services Application&lt;/display-name&gt;
&lt;!-- Set this if you want Resteasy to scan for JAX-RS classes--&gt;
&lt;context-param&gt;
&lt;param-name&gt;resteasy.scan&lt;/param-name&gt;
&lt;param-value&gt;true&lt;/param-value&gt;
&lt;/context-param&gt;

&lt;listener&gt;
&lt;listener-class&gt;org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap&lt;/listener-class&gt;
&lt;/listener&gt;

&lt;servlet&gt;
&lt;servlet-name&gt;Resteasy&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher&lt;/servlet-class&gt;
&lt;/servlet&gt;

&lt;servlet-mapping&gt;
&lt;servlet-name&gt;Resteasy&lt;/servlet-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;

&lt;session-config&gt;
&lt;session-timeout&gt;30&lt;/session-timeout&gt;
&lt;/session-config&gt;
&lt;/web-app&gt;
</pre>
<div>The key entry in the web.xml to make a note of is resteasy.scan. By setting this property to true, on startup the RESTEasy runtime evaluates all deployed class files and determines if any are REST related and registers them appropriately. Get the latest RESTEasy project related files at the download site. I am using RESTEasy version GA 1.1. Within the WEB-INF/lib folder add all dependant jars. These can be found within the resteasy-jaxrs.war\WEB-INF\lib folder of the download. Copy the files in the RESTWeb project lib folder and start the Tomcat server. Refer the SysDeo plugin documentation for project specific settings. In the Tomcat logs you will notice the following warning message:</div>
<div><span style="font-family:Consolas, Monaco, 'Courier New', Courier, monospace;line-height:18px;font-size:12px;white-space:normal;">SLF4J: Class path contains multiple SLF4J bindings.<br />
SLF4J: Found binding in [jar:file:/E:/eclipse/workspace/REST/rest/WEB-INF/lib/slf4j-simple-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]<br />
SLF4J: Found binding in [jar:file:/E:/eclipse/workspace/REST/rest/WEB-INF/lib/slf4j-simple1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]</span></div>
<div><span style="font-family:Consolas, Monaco, 'Courier New', Courier, monospace;line-height:18px;font-size:12px;white-space:normal;"><br />
</span></div>
<div>This is caused by the presence of two slf4j files, namely slf4j-api-1.5.8.jar and slf4j-simple-1.5.8.jar. Remove the file slf4j-simple-1.5.8.jar from the lib folder and restart the Tomcat and the warning messages will not appear.Now let&#8217;s set up the REST specific files. RESTEasy project extensively uses annotations to add REST flavour to Java classes. For our tutorial I am setting up three class files namely, InsuranceProduct, InsuranceProductListing and InsuranceProductService. InsuranceProductService represents the REST specific classes and InsuranceProduct and InsuranceProductListing represents data classes. Here&#8217;s their structure (package name and import statements have been removed for better legibility):</div>
<pre>--------------------- Start InsuranceProductService ----------------------------

@Path("/insurance")
public class InsuranceProductsService {

	@GET
	@Path("/products")
	public String getProducts() {
		InsuranceProductListing listing = new InsuranceProductListing();
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProductListing.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(listing, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

	@GET
	@Path("/product")
	public String getProduct(){
		InsuranceProduct product = new InsuranceProductListing().getProduct();
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProduct.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(product, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

	@GET
	@Path("/list")
	public String getList(){
		List&lt;InsuranceProduct&gt; products = new InsuranceProductListing().getProducts();
		try {
			JAXBContext ctx = JAXBContext.newInstance(ArrayList.class, InsuranceProduct.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(products, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

	@GET
	@Path("/product/{name}")
	public String getProduct(@PathParam("name") String name) {
		InsuranceProduct product = new InsuranceProductListing().getProduct(name);
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProduct.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(product, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

	@GET
	@Path("/product")
	public String getProductByParameter(@QueryParam("name") String name) {
		InsuranceProduct product = new InsuranceProductListing().getProduct(name);
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProduct.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(product, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

	@GET
	@Path("/product")
	public String getProductByMatrix(@MatrixParam("name") String name) {
		InsuranceProduct product = new InsuranceProductListing().getProduct(name);
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProduct.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(product, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}

}

--------------------- End InsuranceProductService ----------------------------------------

--------------------- Start InsuranceProductListing --------------------------------------

@XmlRootElement(name="insuranceProducts")
@XmlSeeAlso({InsuranceProduct.class})
public class InsuranceProductListing {

	private List&lt;InsuranceProduct&gt; products = new ArrayList&lt;InsuranceProduct&gt;();

	private static InsuranceProduct NULL_PRODUCT = null;

	static {
		NULL_PRODUCT = new InsuranceProduct();
	}

	private InsuranceProduct product = null;

	{
		InsuranceProduct product1 = new InsuranceProduct();
		product1.setName("TermLife");

		product1.addDuration("5 years");
		product1.addDuration("10 years");
		product1.addDuration("15 years");
		product1.addDuration("20 years");
		product1.addDuration("25 years");

		this.products.add(product1);
		this.product = product1;

		InsuranceProduct product2 = new InsuranceProduct();
		product2.setName("WholeLife");

		product2.addDuration("5 years");
		product2.addDuration("10 years");
		product2.addDuration("15 years");
		product2.addDuration("20 years");
		product2.addDuration("25 years");

		this.products.add(product2);

	}

	@XmlElement(name="product", type=InsuranceProduct.class)
	public List&lt;InsuranceProduct&gt; getProducts() {
		return this.products;
	}

	public void setProducts(InsuranceProduct[] productsArray) {
		this.products = Arrays.asList(productsArray);
	}

	private InsuranceProduct[] getProductArray(List&lt;InsuranceProduct&gt; prodList) {

		InsuranceProduct[] prodArray = new InsuranceProduct[prodList.size()];
		for (int i = 0; i &lt; prodList.size(); i++) {
			prodArray[i] = prodList.get(i);
		}
		return prodArray;
	}

	public InsuranceProduct getProduct() {
		return this.product;
	}

	public InsuranceProduct getProduct(String name) {
		if (name == null){
			return NULL_PRODUCT;
		}
		for (InsuranceProduct product : this.products) {
			if (name.equals(product.getName())) {
				return product;
			}
		}
		return NULL_PRODUCT;
	}

}

--------------------- End InsuranceProductListing ----------------------------------------

--------------------- Start InsuranceProduct ---------------------------------------------
@XmlRootElement(name="product")
@XmlType(propOrder={"name", "duration"})
public class InsuranceProduct {

	private String name = null;
	private List&lt;String&gt; durations = new ArrayList&lt;String&gt;();

	@XmlElement
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@XmlElement(name="duration")
	@XmlElementWrapper(name="durations")
	public String[] getDuration() {
		return getStringArray(this.durations);
	}

	public void setDuration(List duration) {
		this.durations = duration;
	}

	public void addDuration(String duration) {
		this.durations.add(duration);
	}

	private String[] getStringArray(List&lt;String&gt; durationList) {

		String[] durationArray = new String[durationList.size()];
		for (int i = 0; i &lt; durationList.size(); i++) {
			durationArray[i] = durationList.get(i);
		}
		return durationArray;
	}

}

--------------------- End InsuranceProduct -----------------------------------------------</pre>
<p>Let&#8217;s begin with understanding how a POJO class is enhanced with annotations to make it RESTful. Refer the Insurance ProductService class. The first line it contains is</p>
<p>@Path(&#8220;/insurance&#8221;)</p>
<p>This establishes the relative URL to access a specific functionality within the InsuranceProductService class. Based on the current configuration, the class can be accessed using the URL: http://&lt;servername&gt;:&lt;port&gt;/rest/insurance. Note this URL by itself will not retrieve anything, this will be used in conjunction with additional relative part mentioned alongwith the individual class method. Let me explain how.</p>
<p>Let&#8217;s look at the method getProducts defined within the class. The method is appended with two annotations namely @GET and @Path. The @GET annotations specifies that this is a RESTful Web Service with semantic compliance to the HTTP GET method. The @Path annotation specifies the sub-path which needs to be appended to the class&#8217;s @Path annotation. So to invoke the RESTful Web Service, type the URL http://&lt;servername&gt;:&lt;port&gt;/rest/insurance/products in your browser. The browser will display the following XML:</p>
<pre> &lt;?xml version="1.0" encoding="UTF-8" standalone="yes" ?&gt;
- &lt;insuranceProducts&gt;
- &lt;product&gt;
  &lt;name&gt;TermLife&lt;/name&gt;
- &lt;durations&gt;
  &lt;duration&gt;5 years&lt;/duration&gt;
  &lt;duration&gt;10 years&lt;/duration&gt;
  &lt;duration&gt;15 years&lt;/duration&gt;
  &lt;duration&gt;20 years&lt;/duration&gt;
  &lt;duration&gt;25 years&lt;/duration&gt;
  &lt;/durations&gt;
  &lt;/product&gt;
- &lt;product&gt;
  &lt;name&gt;WholeLife&lt;/name&gt;
- &lt;durations&gt;
  &lt;duration&gt;5 years&lt;/duration&gt;
  &lt;duration&gt;10 years&lt;/duration&gt;
  &lt;duration&gt;15 years&lt;/duration&gt;
  &lt;duration&gt;20 years&lt;/duration&gt;
  &lt;duration&gt;25 years&lt;/duration&gt;
  &lt;/durations&gt;
  &lt;/product&gt;
  &lt;/insuranceProducts&gt;</pre>
<p>Let&#8217;s try and understand the code written within the getProducts method. The code is as below:</p>
<pre>	public String getProducts() {
		InsuranceProductListing listing = new InsuranceProductListing();
		try {
			JAXBContext ctx = JAXBContext.newInstance(InsuranceProductListing.class);
			Marshaller marshaller = ctx.createMarshaller();
			StringWriter sw = new StringWriter();
			marshaller.marshal(listing, sw);
			return sw.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;

	}</pre>
<p>The getProducts method returns the response XML as a String. Therefore, the method implementation needs to convert the Java object(s) into its corresponding XML format. This is facilitated in RESTEasy via JAXB. The code written within the try catch block is the JAXB code to convert the InsuranceProductListing object into its equivalent XML representation. Please do take note of one thing, the class name specified in the parameter of the newInstance method of JAXBContext and the object passed in the Marshaller object&#8217;s marshal method should be the same else you might be accosted by the following exception:</p>
<pre>JAXBException: xxx.xxx.Xxxxx nor any of its super class is known to this context</pre>
<p>Now we need to look at the aspects that need to be added to the InsuranceProductListing class to make its properties marshallable for responding to getProducts request. The first and foremost entry that is required within the InsuranceProductListing class is to specify that it is a XMLRootElement. This is specified by the @XmlRootElement annotation. The name attribute defines the XML root tag name. The @XmlSeeAlso annotation helps specify the additional dependant classes referred in this class.</p>
<pre>@XmlRootElement(name="insuranceProducts")
@XmlSeeAlso({InsuranceProduct.class})
public class InsuranceProductListing {<span style="font-size:small;">
</span></pre>
<div>Next we need to define the elements/attributes of the response xml. This is done by defining using the @XmlElement annotation. Likewise it has @XmlAttribute annotation for attribute definition.</div>
</div>
<pre>@XmlElement(name="product", type=InsuranceProduct.class)
public List&lt;InsuranceProduct&gt; getProducts() {
	return this.products;
}<span style="font-family:Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;"><span style="line-height:19px;white-space:normal;font-size:x-small;">
</span></span></pre>
<p><span style="font-family:Consolas, Monaco, 'Courier New', Courier, monospace;"><span style="line-height:18px;white-space:pre;font-size:small;"><span style="font-family:Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;"><span style="line-height:19px;white-space:normal;">Similar defintions need to be done within InsuranceProduct class. Just one more thing to note, in case you have a requirement where the elements need to be displayed in a specific order, that can be specified as a class level @XmlType annotation for e.g. in InsuranceProduct, it is defined by the following line:</span></span></span></span></p>
<pre>@XmlType(propOrder={"name", "duration"})</pre>
<p>For collections, by default the JAXB implementation does not provide a wrapper tag, we can add it by using the @XmlElementWrapper annotation. For example, in InsuranceProduct class for the durations List, we have implemented it  in the following manner:</p>
<pre>@XmlElementWrapper(name="durations")</pre>
<p>Now let&#8217;s look at the method getList. Unlike the getProducts method which returns a InsuranceProductListing class that acts as a wrapper for list of InsuranceProduct objects, the getList method returns a List of InsuranceProduct. This invocation fails with the following exception:</p>
<pre>unable to marshal type "java.util.ArrayList" as an element because it is missing an @XmlRootElement annotation<span style="font-size:small;">
</span></pre>
<div>Basically RESTEasy does not support methods that define ArrayList or Array etc as their root level objects. Now let us move on to passing search parameters to our RESTful Web Service requests. RESTEasy supports three different mechanisms:</p>
<ul>
<li>PathParam</li>
<li>QueryParam</li>
<li>MatrixParam</li>
</ul>
<p>The implementations can be viewed by referring to the getProduct, getProductByParameter and getProductByMatrix methods respectively. For PathParam the URL is http://&lt;servername&gt;:&lt;port&gt;/rest/insurance/product/TermLife, for queryParam the URL is http://&lt;servername&gt;:&lt;port&gt;/rest/insurance/product?name=WholeLife and for matrixParam the URL is http://&lt;servername&gt;:&lt;port&gt;/rest/insurance/product;name=TermLife. QueryParam and MatrixParam support multiple input parameters. There are other param options such as CookieParam or FormParam to retrieve information from the corresponding web application component.</p>
<p>That&#8217;s all from the REST desk for now.</p>
</div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/183/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=183&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/10/13/restful-webservices-using-jboss-resteasy-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>java.util.concurrent.atomic: How to use Java Atomic Classes? AtomicInteger</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/08/28/java-util-concurrent-atomic-atomicinteger/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/08/28/java-util-concurrent-atomic-atomicinteger/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 13:58:48 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=173</guid>
		<description><![CDATA[It has been some time since the release of Java 5. It introduced a number of improvements in terms of classes to handle concurrency concerns. Today I will cruising thru the java.util.concurrent.atomic package and looking at the package&#8217;s relevance in tackling real-life issues.

Let&#8217;s get started with the most basic requirements. Assume that you have a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=173&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>It has been some time since the release of Java 5. It introduced a number of improvements in terms of classes to handle concurrency concerns. Today I will cruising thru the java.util.concurrent.atomic package and looking at the package&#8217;s relevance in tackling real-life issues.</p>
<p><span id="more-173"></span></p>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">Let&#8217;s get started with the most basic requirements. Assume that you have a web site that maintains the number of users accessing a page. The counter information is not persisted beyond the web site up time. Therefore, we just need a counter to maintain a count of the number of users accessing a page. This can be achieved by creating a counter which is incremented on every page access. To ensure precise measurement, the counter needs to be incremented by a single thread and no other thread should access the counter variable. In pre Java 5 days, we would have to control access to the counter variable using a synchronized block. Here&#8217;s the sample code to do it:</div>
<p>Let&#8217;s get started with the most basic requirements. Assume that you have a web site that maintains the number of users accessing a page. The counter information is not persisted beyond the web site up time. Therefore, we just need a counter to maintain a count of the number of users accessing a page. This can be achieved by creating a counter which is incremented on every page access. To ensure precise measurement, the counter needs to be incremented by a single thread and no other thread should access the counter variable. In pre Java 5 days, we would have to control access to the counter variable using a synchronized block. Here&#8217;s the sample code to do it:</p>
<pre>class Counter {

	private int count = 0;

	Counter () {

	}

	synchronized void increment() {
		count++;
	}

	int getCount() {
		return count;
	}
}</pre>
<p>The synchronized is an all or nothing block. Java 5 provides an improved solution to handle the problem instead use the java.util.concurrent.atomic.AtomicInteger. This class implements the behavior as expected from Counter and in a more efficient manner. I have created the following test codes to verify the results:</p>
<pre>public class CounterTest {

	public static void main(String[] args) {

		Counter counter = new Counter();

		for(int i=0; i&lt; 1600; i++) {
			//This loop to get rid of any hotspot optimizations
			counter.increment();
		}

		long startTime = System.nanoTime();

		for(int i=0; i&lt; 150000; i++) {
			counter.increment();
		}

		long endTime = System.nanoTime();
		double processingTime = (endTime - startTime)/Math.pow(10, 6);

		System.out.println("Processing Time (msec): " + processingTime + " Count: " + counter.getCount());

	}

}

public class AtomicIntegerTest {

	public static void main(String[] args) {
		AtomicInteger counter = new AtomicInteger(0);

		for(int i=0; i&lt; 1600; i++) {
			//This loop to get rid of any hotspot optimizations
			counter.incrementAndGet();
		}

		long startTime = System.nanoTime();

		for(int i=0; i&lt; 150000; i++) {
			counter.incrementAndGet();
		}

		long endTime = System.nanoTime();
		double processingTime = (endTime - startTime)/Math.pow(10, 6);

		System.out.println("Processing Time (msec): " + processingTime + " Count: " + counter.intValue());

	}

}</pre>
<address>
<address>Running CounterTest displays the following:</address>
<address>Processing Time (msec): 18.196106 Count: 151600</address>
<address></address>
<address></address>
<address>Running AtomicIntegerTest displays the following:</address>
<address>Processing Time (msec): 11.212189 Count: 151600</address>
</address>
<div>There is a considerable improvement in performance. OK the next question is whether the counter is incrementing properly. Here&#8217;s how I tested it:</div>
<pre>public class ConcurrencyTest {

	public static void main(String[] args) {
		AtomicInteger counter = new AtomicInteger(0);

		for(int i=0; i&lt;100; i++) {
			Runnable runnable = new WorkerThread(counter);
			Thread t = new Thread(runnable);
			t.start();
		}

	}

}

class WorkerThread implements Runnable {

	AtomicInteger count = null;

	WorkerThread(AtomicInteger counter) {
		this.count = counter;
	}

	public void run() {
		int value = this.count.incrementAndGet();
		System.out.println(value);
	}
}</pre>
<div>The output of the ConcurrencyTest run is a sequential value starting from 1 and ending at 100.</p>
<p>There are AtomicIntegerArray and AtomicLongArray classes.Apparently there is no AtomicFloat or AtomicDouble. The reason is explained in a foot note in the package summary.</p>
<p>You can also hold floats using Float.floatToIntBits and Float.intBitstoFloat conversions, and doubles using Double.doubleToLongBits and Double.longBitsToDouble conversions.</p></div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/173/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/173/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/173/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/173/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/173/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/173/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=173&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/08/28/java-util-concurrent-atomic-atomicinteger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>Setting anonymous/stealth login to web applications &#8211; the HTTPUnit way</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/07/12/setting-anonymousstealth-login-to-web-applications-the-httpunit-way/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/07/12/setting-anonymousstealth-login-to-web-applications-the-httpunit-way/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 12:44:34 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[HTTPUnit]]></category>
		<category><![CDATA[stealth login]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=163</guid>
		<description><![CDATA[public class Processor {
 
 public Processor() {
 
 }
 
 public String getHTML() {
 WebConversation conversation = new WebConversation();
 WebRequest req = new GetMethodWebRequest(&#8220;http://www.abc.com/login&#8221;);
 try {
 HttpUnitOptions.setScriptingEnabled(true);
 HttpUnitOptions.setExceptionsThrownOnScriptError(false);
 WebResponse res = conversation.getResource(req);
 WebForm form = res.getForms()[0];
 String formName = form.getName();
 
 form.setParameter(&#8220;user&#8221;, &#8220;test&#8221;);
 form.setParameter(&#8220;password&#8221;, &#8220;pwd&#8221;);
 WebResponse formResponse = form.submit();
 String htmlText = formResponse.getText();
 return [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=163&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">public class Processor {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>public Processor() {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>}</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>public String getHTML() {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>WebConversation conversation = new WebConversation();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>WebRequest req = new GetMethodWebRequest(&#8220;http://www.abc.com/login&#8221;);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>try {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>HttpUnitOptions.setScriptingEnabled(true);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>HttpUnitOptions.setExceptionsThrownOnScriptError(false);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>WebResponse res = conversation.getResource(req);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>WebForm form = res.getForms()[0];</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>String formName = form.getName();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>form.setParameter(&#8220;user&#8221;, &#8220;test&#8221;);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>form.setParameter(&#8220;password&#8221;, &#8220;pwd&#8221;);</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>WebResponse formResponse = form.submit();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>String htmlText = formResponse.getText();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>return htmlText;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>} catch (IOException e) {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>// TODO Auto-generated catch block</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>e.printStackTrace();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>} catch (SAXException e) {</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>// TODO Auto-generated catch block</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>e.printStackTrace();</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>}</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span></div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>return null;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;"><span style="white-space:pre;"> </span>}</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">}</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">I am currently working on setting up Oracle WebCenter/Oracle Weblogic portal for developing a sample application. One of the aspects we need to take care of is provide navigable links to other core as well as support applications. In the production set up all the applications will be hooked up using Single Sign On(SSO), however in the demo version we are not using a SSO setup. Each application has its individual login page. Therefore, while navigating from one application to another, or from the portal to individual application, the user needs to supply security credentials, this is irritating from an user experience point of view.</div>
<p>I am currently working on setting up Oracle WebCenter/Oracle Weblogic portal for developing a sample application. One of the aspects we need to take care of is provide navigable links to other core as well as support applications. In the production set up all the applications will be hooked up using Single Sign On(SSO), however in the demo version we are not using a SSO setup. Each application has its individual login page. Therefore, while navigating from one application to another, or from the portal to individual application, the user needs to supply security credentials, this is irritating from an user experience point of view.</p>
<p><span id="more-163"></span></p>
<p>To circumvent the problem, I started looking at ways and means of invoking the page behind the scene. Basically I was looking for the behavior associated with typical web application testing tool. My search lead me to a tool named <a title="HTTPUnit" href="http://httpunit.sourceforge.net/" target="_blank">HTTPUnit</a>. It provides methods to execute HTTP requests and process HTTP responses via Java programs. Here&#8217;s the sample program that I created (Note: the package name and package imports have been removed for better comprehension):</p>
<pre>1:public class BPMTest {
2:
3:	public static void main(String[] args) {
4:
5:		WebConversation conversation = new WebConversation();
6:		WebRequest req = new GetMethodWebRequest(&lt;HTTP REQUEST URL&gt;);
7:		try {
8:			//HttpUnitOptions.setScriptingEnabled(false);
9:			WebResponse res = conversation.getResource(req);
10:			//String s = res.getText();
11:			//System.out.println(s);
12:			WebForm form = res.getForms()[0];
13:			String formName = form.getName();
14:			String[] params = form.getParameterNames();
15:
16:			for (String paramName : params) {
17:				System.out.println(paramName);
18:			}
19:
20:			form.setParameter("user", &lt;USERNAME&gt;);
21:			form.setParameter("password", &lt;PASSWORD&gt;);
22:			WebResponse formResponse = form.submit();
23:
24:			String s = formResponse.getText();
25:			System.out.println(s);
26:
27:		} catch (IOException e) {
28:			e.printStackTrace();
29:		} catch (SAXException e) {
30:			e.printStackTrace();
31:		}
32:
33:
34:	}
35:
36:}
<span style="font-family:Georgia;line-height:19px;white-space:normal;font-size:13px;">Running this program in my case generated a error message:</span></pre>
<pre>org.mozilla.javascript.EcmaError: TypeError: Cannot find function attachEvent. (httpunit#50)
	at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3229)
	at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3219)
	at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3235)</pre>
<p><span style="font-family:Georgia;line-height:19px;white-space:normal;font-size:13px;"> </span></p>
<div>As I understand it, there are certain Javascript events not supported in HTTPUnit, hence the error. As per Google, the fix is to use <a title="HTMLUnit" href="http://htmlunit.sourceforge.net/" target="_blank">HTMLUnit</a>, which apparently provides better support for Javascript. Fortunately, HTTPUnit is configurable, I uncommented line 8 in the code. This allows HTTPUnit&#8217;s Javascript processing to be bypassed. The code ran without any errors and I could process the response. However if you are greedy and want HTTPUnit to process as much Javascript as possible do the following. Replace line 8 with the following lines of code:</div>
<pre>	HttpUnitOptions.setScriptingEnabled(true);
	HttpUnitOptions.setExceptionsThrownOnScriptError(false);</pre>
<div>This enables HTTPUnit Javascript but does not throw any exceptions on encountering errors during Javascript processing.<br />
Let&#8217;s understand the features provided by HTTPUnit. The tool provides access to forms within the web page(line 12). One can key in information to the form and submit it(line 20-22). The HTML generated as a response to the form submission is available via the getText method of WebResponse(line 24).</div>
<div>Now to integrate this solution with our requirement. To test this in the web world, I developed a small web application and deployed it on Tomcat server. You will find enough material on the web to set up this configuration. The following are the most important components. The test page test.jsp, the web.xml and Processor code:</div>
<div>
<div>CODE for web.xml (for Tomcat server only)</div>
<div>Located within the &lt;application-root&gt;/WEB-INF folder.</div>
</div>
<pre>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"&gt;
  	&lt;servlet&gt;
    	&lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
    	&lt;servlet-class&gt;org.apache.jasper.servlet.JspServlet&lt;/servlet-class&gt;
    	&lt;init-param&gt;
      		&lt;param-name&gt;fork&lt;/param-name&gt;
      		&lt;param-value&gt;false&lt;/param-value&gt;
    	&lt;/init-param&gt;
    	&lt;init-param&gt;
      		&lt;param-name&gt;xpoweredBy&lt;/param-name&gt;
      		&lt;param-value&gt;false&lt;/param-value&gt;
    	&lt;/init-param&gt;
    	&lt;init-param&gt;
			&lt;param-name&gt;logVerbosityLevel&lt;/param-name&gt;
			&lt;param-value&gt;WARNING&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;classdebuginfo&lt;/param-name&gt;
			&lt;param-value&gt;true&lt;/param-value&gt;
		&lt;/init-param&gt;
    	&lt;load-on-startup&gt;3&lt;/load-on-startup&gt;
  	&lt;/servlet&gt;

	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
	    &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;servlet-mapping&gt;
	    &lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
	    &lt;url-pattern&gt;*.jspx&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;session-config&gt;
	    &lt;session-timeout&gt;30&lt;/session-timeout&gt;
	&lt;/session-config&gt;

	&lt;welcome-file-list&gt;
	    &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
	    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;

&lt;/web-app&gt;</pre>
<div>
<div>CODE for Processor</div>
<div>Located within the &lt;application-root&gt;/WEB-INF/classes folder</div>
</div>
<pre>public class Processor {

	public Processor() {

	}

	public String getHTML() {
		WebConversation conversation = new WebConversation();
		WebRequest req = new GetMethodWebRequest("http://www.abc.com/login");
		try {
			HttpUnitOptions.setScriptingEnabled(true);
			HttpUnitOptions.setExceptionsThrownOnScriptError(false);
			WebResponse res = conversation.getResource(req);
			WebForm form = res.getForms()[0];
			String formName = form.getName();

			form.setParameter("user", "test");
			form.setParameter("password", "pwd");
			WebResponse formResponse = form.submit();
			String htmlText = formResponse.getText();
			return htmlText;

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;

	}

}</pre>
<div><span style="font-family:Consolas;font-size:small;"><span style="line-height:18px;white-space:pre;"></p>
<div><span style="font-family:Georgia;line-height:19px;white-space:normal;">CODE for test.jsp</span></div>
<div><span style="font-family:Georgia;line-height:19px;white-space:normal;">Located within the &lt;application-root&gt;</span></div>
<div><span style="font-size:12px;">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;ISO-8859-1&#8243; ?&gt;</span></div>
<pre>&lt;%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%&gt;
&lt;jsp:useBean id="proc" class="com.test.Processor" scope="page"/&gt;

&lt;%
	out.println(proc.getHTML());
%&gt;</pre>
<div><span style="font-family:Georgia;line-height:19px;white-space:normal;">Running the test.jsp displays the response page generated on submitting login information to the http://www.abc.com/login URL. However there are certain limitations,</span></div>
<div><span style="font-family:Georgia;line-height:19px;white-space:normal;"></p>
<ol>
<li>The Javascript support is not extensive. If the page is largely dependent on Javascript for its display then you may have problems.</li>
<li>As a best practice, URLs in web pages are relative, this causes the resultant page displaying URLs relative to your tomcat server and not www.abc.com server. Therefore, the web application would need to be deployed on the individual remote application and not at a single separate location.</li>
</ol>
<p></span></div>
<div><span style="font-family:Georgia;line-height:19px;white-space:normal;">As a part of this dependant jar libraries, it provides a servlet-api-2.4.jar, ensure that this jar is not deployed in the WEB-INF/lib folder.  I might try HTMLUnit to check its Javascript support. More on that later.</span></div>
<p></span></span></div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/163/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=163&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/07/12/setting-anonymousstealth-login-to-web-applications-the-httpunit-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>JBoss Drools &#8211; Business Rules Management System/Guvnor</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/05/22/jboss-drools-business-rules-management-systemguvnor/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/05/22/jboss-drools-business-rules-management-systemguvnor/#comments</comments>
		<pubDate>Fri, 22 May 2009 06:02:42 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[JBoss]]></category>
		<category><![CDATA[JBoss Drools]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=157</guid>
		<description><![CDATA[I was playing around with the web interface of the JBoss Drools engine called Business Rules Management System or BRMS till version 4.0.7. In the subsequent versions i.e 5.0 it is called Guvnor. While trying to validate the newly defined business rule, I got the following error:
java.lang.ClassFormatError: Incompatible magic value 1885430635 in class file
A quick [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=157&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I was playing around with the web interface of the JBoss Drools engine called Business Rules Management System or BRMS till version 4.0.7. In the subsequent versions i.e 5.0 it is called Guvnor. While trying to validate the newly defined business rule, I got the following error:</p>
<blockquote><p>java.lang.ClassFormatError: Incompatible magic value 1885430635 in class file</p></blockquote>
<p>A quick search on the internet revealed the <a title="JBoss Drools BRMS - ClassFormatError QuickFix" href="http://www.jroller.com/sureshrk19/entry/guvnor_java_lang_classformaterror_incompatible" target="_blank">answer</a>. Please ensure that your java class jar files contain only .class files and not source code. Weird yes, but that&#8217;s how it is!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/157/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=157&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/05/22/jboss-drools-business-rules-management-systemguvnor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>JBoss Drools &#8211; Defining business rules</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/05/20/jboss-drools-defining-business-rules/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/05/20/jboss-drools-defining-business-rules/#comments</comments>
		<pubDate>Wed, 20 May 2009 14:40:25 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[Drools]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=154</guid>
		<description><![CDATA[The last two articles focused on some of the current projects that I was working on. So after kick starting Drools(4.0.7), I lost track and wrote some posts on JBoss clustering. Interesting as they were, I want to get back on defining business rules using JBoss Drools. I am just taking up from where I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=154&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div id="_mcePaste" style="position:absolute;left:-10000px;top:0;width:1px;height:1px;">The last two articles focused on some of the current projects that I was working on. So after kick starting Drools(4.0.7), I lost track and wrote some posts on JBoss clustering. Interesting as they were, I want to get back on defining business rules using JBoss Drools. I am just taking up from where I left off in my last Drools post. In my last post, I covered how Drools can use MS Excel spreadsheets to implement decision tables. Now I am going to talk about implementing business rules using a DRL.</div>
<p>The last two articles focused on some of the current projects that I was working on. So after <a title="JBoss Drools - Decision Tables" href="http://technicalmumbojumbo.wordpress.com/2009/03/28/jboss-drools-decision-tables/" target="_blank">kick starting</a> Drools(4.0.7), I lost track and wrote some posts on JBoss clustering. Interesting as they were, I want to get back on defining business rules using JBoss Drools. I am just taking up from where I left off in my last Drools <a title="JBoss Drools - Decision Tables" href="http://technicalmumbojumbo.wordpress.com/2009/03/28/jboss-drools-decision-tables/" target="_blank">post</a>. In my last post, I covered how Drools can use MS Excel spreadsheets to implement decision tables. Now I am going to talk about implementing business rules using a DRL. You could treat this as a tutorial.</p>
<p><span id="more-154"></span></p>
<p>Please find below a sample DRL file, I have implemented. The idea here is to understand the various elements and operators provided by Drools and how to utilize them in an actual business scenario.</p>
<pre>package IssueRules

#list any import classes here.
import com.ins.Policy;
import com.ins.PolicyProduct;
import com.ins.Coverage;
import java.util.ArrayList;

#declare any global variables here
global com.ins.result.PolicyRuleResult result;
#global com.ins.PolicyProduct policyProd;

rule "Determine if any one of coverages are eligible for Issue"
	salience 100
	when
		$policy : Policy()
		exists ($coverage : Coverage(eligible == true) from $policy.coverages)
	then
		result.setEligible(Boolean.TRUE);

end

rule "Determine if all of coverages are eligible for Issue"
	salience 99
	when
		$policy : Policy()
		not (exists(Coverage(eligible == false) from $policy.coverages))

	then
		result.setAllCoveragesAreEligible(Boolean.TRUE);

end

rule "Determine if agent information captured is valid"
	salience 98
	when
		$policy : Policy( agents contains "Bill Smith")

	then
		result.setAgentInformationValid(Boolean.TRUE);

end

rule "Determine if product can be sold in the specific state"
	salience 97
	when
		$policyProd : PolicyProduct()
		Policy(issueState memberOf  $policyProd.states)
	then
		result.setApprovedState(Boolean.TRUE);

end

rule "Check out the soundex function of Drools"
	# check if any insured name matches a particular pattern
	salience 96
	when
		$policy : Policy()
		exists ($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the soundex function of Drools - minor change"
	# check if any insured name matches a particular pattern with a minor variation
	salience 95
	when
		$policy : Policy()
		$coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the collect function of Drools and collect functionality diff from function"
	salience 94
	when
		$policy : Policy()
		$coverages : ArrayList(size == 2)
			from collect($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.setSoundexWorksCollect(Boolean.TRUE);
end

rule "Check if the coverages are valid and satisfy gender, age, faceamount validation rules"
	salience 93
	#no-loop true
	when
		$policy : Policy()
		$coverage : Coverage( (faceAmount &lt; 50000 || faceAmount &gt; 250000) ||
								(	(insured.gender == "M" &amp;&amp; (insured.age &lt; 25 || insured.age &gt; 65))
									||
									(insured.gender == "F" &amp;&amp; (insured.age &lt; 18 || insured.age &gt; 65))
								)
							)
			from $policy.coverages
	then
		$coverage.setEligible(false);
		//update($policy); #Point to be noted Infinite Loop Refer: http://www.mail-archive.com/rules-users@lists.jboss.org/msg07671.html
end

rule "Return value identifier sample"
	salience 92
	#no-loop true
	when
		$policy : Policy()
		$coverage1: Coverage (faceAmount == 250000, insured.gender == "F", $age : insured.age) from $policy.coverages
		$coverage2: Coverage (insured.gender == "F", insured.age == ($age+15)) from $policy.coverages
	then
		result.setRetIdentifier(Boolean.TRUE);
		//update($policy); #Point to be noted Infinite Loop Refer: http://www.mail-archive.com/rules-users@lists.jboss.org/msg07671.html
end

rule "Compute the total and average faceamount per coverage"
	salience 91
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							init (double total =0;),
							action (total += $amt;),
							reverse(total -= $amt;),
							result(total)
						)
	then
		result.setTotalFaceAmount(new Integer($total.intValue()));
end

rule "Compute the total in a simpler fashion"
	salience 90
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							sum($amt)
						)
	then
		result.setTotalFaceAmountSimp(new Integer($total.intValue()));
end

rule "Compute the average faceamount per coverage"
	salience 89
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							average($amt)
						)
	then
		result.setAverageFaceAmount(new Double($total.doubleValue()));
end

query "Get Insured details for the policy"
	$policy : Policy()
	$coverages : Coverage($insured: insured ) from $policy.coverages
end</pre>
<p>To explain the implementation, I have created some sample Java files, Policy, PolicyProduct, Coverage and PolicyRuleResult.</p>
<pre>##Policy.java
package com.ins;

import java.util.ArrayList;
import java.util.List;

public class Policy {

	private List&lt;Coverage&gt; coverages = new ArrayList&lt;Coverage&gt;();

	private List&lt;String&gt; agents = new ArrayList&lt;String&gt;();
	private String issueState = null;
	private List&lt;String&gt; sample = new ArrayList&lt;String&gt;();

	public List&lt;Coverage&gt; getCoverages() {
		return coverages;
	}

	public void setCoverages(List&lt;Coverage&gt; coverages) {
		this.coverages = coverages;
	}

	public void addCoverage(Coverage coverage) {
		this.coverages.add(coverage);
	}

	public List&lt;String&gt; getAgents() {
		return agents;
	}

	public void setAgents(List&lt;String&gt; agents) {
		this.agents = agents;
	}

	public void addAgent(String agentName) {
		this.agents.add(agentName);
	}

	public List&lt;String&gt; getSample() {
		return sample;
	}

	public void setSample(List&lt;String&gt; sample) {
		this.sample = sample;
	}

	public String getIssueState() {
		return issueState;
	}

	public void setIssueState(String issueState) {
		this.issueState = issueState;
	}

}

##Policy.java

##PolicyProduct.java
package com.ins;

import java.util.ArrayList;
import java.util.List;

public class PolicyProduct {

    private List&lt;String&gt; states = new ArrayList&lt;String&gt;();

    {
    	states.add("VA");
    	states.add("WI");
    	states.add("NY");
    }

	public List&lt;String&gt; getStates() {
		return states;
	}

	public void setStates(List&lt;String&gt; states) {
		this.states = states;
	}

}

##PolicyProduct.java
##Coverage.java
package com.ins;

public class Coverage {

	private boolean eligible = false;

	private Insured insured = null;

	private int faceAmount = 0;

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

	public Insured getInsured() {
		return insured;
	}

	public void setInsured(Insured insured) {
		this.insured = insured;
	}

	public int getFaceAmount() {
		return faceAmount;
	}

	public void setFaceAmount(int faceAmount) {
		this.faceAmount = faceAmount;
	}

}

##Coverage.java
##Insured.java
package com.ins;

public class Insured {

	private String firstName = null;

	private String lastName = null;

	private int age = 0;

	private String gender = null;

	public static final String GENDER_MALE = "M";
	public static final String GENDER_FEMALE = "F";

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

}

##Insured.java
##PolicyRuleResult.java
package com.ins.result;

import java.util.ArrayList;
import java.util.List;

public class PolicyRuleResult {

	private boolean eligible = false;
	private boolean allCoveragesAreEligible = false;
	private boolean agentInformationValid = false;
	private boolean approvedState = false;
	private List&lt;String&gt; soundMessages = new ArrayList&lt;String&gt;();
	private boolean soundexWorksCollect = false;
	private boolean retIdentifier = false;
	private Integer totalFaceAmount = null;
	private Integer totalFaceAmountSimp = null;
	private Double averageFaceAmount = null;

	public boolean isAllCoveragesAreEligible() {
		return allCoveragesAreEligible;
	}

	public void setAllCoveragesAreEligible(boolean allCoveragesAreEligible) {
		this.allCoveragesAreEligible = allCoveragesAreEligible;
	}

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

	public boolean isAgentInformationValid() {
		return agentInformationValid;
	}

	public void setAgentInformationValid(boolean agentInformationValid) {
		this.agentInformationValid = agentInformationValid;
	}

	public boolean isApprovedState() {
		return approvedState;
	}

	public void setApprovedState(boolean approvedState) {
		this.approvedState = approvedState;
	}

	public void addSoundMessage(String msg) {
		this.soundMessages.add(msg);
	}

	public List&lt;String&gt; getSoundMessages() {
		return this.soundMessages;
	}

	public boolean isSoundexWorksCollect() {
		return soundexWorksCollect;
	}

	public void setSoundexWorksCollect(boolean soundexWorksCollect) {
		this.soundexWorksCollect = soundexWorksCollect;
	}

	public boolean isRetIdentifier() {
		return retIdentifier;
	}

	public void setRetIdentifier(boolean retIdentifier) {
		this.retIdentifier = retIdentifier;
	}

	public Integer getTotalFaceAmount() {
		return totalFaceAmount;
	}

	public void setTotalFaceAmount(Integer totalFaceAmount) {
		this.totalFaceAmount = totalFaceAmount;
	}

	public Integer getTotalFaceAmountSimp() {
		return totalFaceAmountSimp;
	}

	public void setTotalFaceAmountSimp(Integer totalFaceAmountSimp) {
		this.totalFaceAmountSimp = totalFaceAmountSimp;
	}

	public Double getAverageFaceAmount() {
		return averageFaceAmount;
	}

	public void setAverageFaceAmount(Double averageFaceAmount) {
		this.averageFaceAmount = averageFaceAmount;
	}

}
##PolicyRuleResult.java<span>
</span></pre>
<div>A typical rule in Drools is specified in the following format</div>
<pre>rule
	salience &lt;integer value&gt;
	when
		&lt;CONDITION&gt;
	then
		&lt;ACTION&gt;</pre>
<div><span style="font-family:Consolas;line-height:18px;white-space:pre;"><br />
</span></div>
<div>The salience attribute defines the priority, in case there are two rules that satisfy a given condition, the rule with higher salience value is given priority over the other. The &#8220;when&#8221; clause contains the condition to be evaluated and the &#8220;then&#8221; clause retains the action to be taken in case the condition is satisfied. There are other attributes in the Drools format, however I am restricting to the ones I have used in my example.</div>
<div>Let&#8217;s consider the first rule defined in the drl file.</div>
<pre>1: rule "Determine if any one of coverages are eligible for Issue"
2:	salience 100
3:	when
4:		$policy : Policy()
5:		exists ($coverage : Coverage(eligible == true) from $policy.coverages)
6:	then
7:		result.setEligible(Boolean.TRUE);
8: end</pre>
<div>The rule is essentially checking if any of the policy&#8217;s coverages are eligible to be provided cover. The Policy class has an attribute coverages whose data type is a List. Therefore, as per the rule we need to iterate over all the Coverage objects present in the policy and check if the attribute eligible within the Coverage object is set to true. From a rules point of view, we instantiate a variable reference to the Policy object by declaring line 4. We have declared a variablenamed $policy for Policy object. There no specific naming convention. policy : Policy() would have also sufficed. However $policy provides better legibility by clearly demarking policy as a variable reference. Now to iterate over the collection we add the following line:</div>
<pre>from $policy.coverages</pre>
<div>By using $policy.coverages, we are specifying that within the policy variable we are looking at the coverages attribute. &#8220;from&#8221; clause means we are handling a collection. We need to find out if any of the coverages has its eligible attribute set to &#8220;true&#8221; we use the following clause:<br />
$coverage : Coverage(eligible == true) from $policy.coverages<br />
This clause helps retrieve all coverages where eligible attribute is set to true. To confirm via a boolean condition we add the exists conditional element. So the complete clause becomes<br />
exists($coverage : Coverage(eligible == true) from $policy.coverages). Note all java classes referenced in the rule are added in the drl file import statements. Now that we have defined the condition let&#8217;s define the action. Apparently only global variables can be accessed in the action block. We have defined a global variable acroynmed &#8216;result&#8217;. As a an action we set its eligible attribute to true via line 7.</div>
<div>
<p>Great we are done with our first rule. Let&#8217;s write some test code to validate if it runs successfully.</p>
<pre>package com.ins.test;

import java.io.FileReader;
import java.net.URL;
import java.util.Iterator;

import org.drools.QueryResult;
import org.drools.QueryResults;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;

import com.ins.Coverage;
import com.ins.Insured;
import static com.ins.Insured.*;
import com.ins.Policy;
import com.ins.PolicyProduct;
import com.ins.result.PolicyRuleResult;

public class IssueTest {

	public static void main(String args[]) {
        try {

        	//load up the rulebase
            RuleBase ruleBase = readDRL();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            Policy policy = new Policy();
            policy.addAgent("Bill Smith");
            Coverage coverage1 = new Coverage();
            coverage1.setEligible(true);
            coverage1.setFaceAmount(250000);

            Coverage coverage2 = new Coverage();
            coverage2.setEligible(true);
            coverage2.setFaceAmount(1500000);

            policy.addCoverage(coverage1);
            policy.addCoverage(coverage2);
            policy.setIssueState("CO");

            Insured insured1 = new Insured();
            insured1.setFirstName("Elizabeth");
            insured1.setAge(30);
            insured1.setGender(GENDER_FEMALE);
            coverage1.setInsured(insured1);

            Insured insured2 = new Insured();
            insured2.setFirstName("Elizabeth");
            insured2.setAge(45);
            insured2.setGender(GENDER_FEMALE);
            coverage2.setInsured(insured2);

            PolicyRuleResult result = new PolicyRuleResult();
            PolicyProduct policyProd = new PolicyProduct();

            workingMemory.insert(policy);
            workingMemory.insert(policyProd);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(result.isEligible());
            System.out.println(result.isAllCoveragesAreEligible());
            System.out.println(result.isAgentInformationValid());
            System.out.println(result.isApprovedState());
            System.out.println(result.getSoundMessages());
            System.out.println(result.isSoundexWorksCollect());

            System.out.println("Cov1: " + coverage1.isEligible());
            System.out.println("Cov2: " + coverage2.isEligible());

            System.out.println("Ret Id: " + result.isRetIdentifier());
            System.out.println("Total Face Amount: " + result.getTotalFaceAmount());
            System.out.println("Total Face Amount Simp: " + result.getTotalFaceAmountSimp());
            System.out.println("Ave. Face Amount: " + result.getAverageFaceAmount());

            //Query Results
            QueryResults results = workingMemory.getQueryResults("Get Insured details for the policy");
            System.out.println( "we have " + results.size() + " insured(s)" );

            for ( Iterator it = results.iterator(); it.hasNext(); ) {
                QueryResult qResult = (QueryResult)it.next();
                Insured insured = (Insured) qResult.get( "$insured" );
                System.out.println( insured.getFirstName() + "\n" );
            }

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDRL() throws Exception {
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new FileReader(getDRLFilePath()));
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}

	private static String getDRLFilePath() {
		ClassLoader loader = Policy.class.getClassLoader();
		URL url = loader.getResource("IssueRules.drl");
		return url.getPath();
	}
}</pre>
</div>
<div>Note that this test client covers a lot more than what is required for our current requirement, however I wanted test code to be put in once and reused for subsequent rules. Here we need to focus on the result of this line:</div>
<pre>System.out.println(result.isEligible());</pre>
<div>That&#8217;s all.Now let&#8217;s further enhance the rule to ensure that none of the coverages are ineligible for risk cover. Here&#8217;s the rule:</p>
<pre>1:rule "Determine if all of coverages are eligible for Issue"
2:	salience 99
3:	when
4:		$policy : Policy()
5:		not (exists(Coverage(eligible == false) from $policy.coverages))
6:
7:	then
8:		result.setAllCoveragesAreEligible(Boolean.TRUE);
9:
10:end</pre>
</div>
<div>The condition exists(Coverage(eligible == false) from $policy.coverages) checks if any one of the coverage has its eligible attribute set to false. The not conditional element makes sure that not even one of the coverage has its eligible attribute set to false.Now let&#8217;s look at two operators at the same time.</p>
<pre>rule "Determine if agent information captured is valid"
	salience 98
	when
		$policy : Policy( agents contains "Bill Smith")

	then
		result.setAgentInformationValid(Boolean.TRUE);

end

rule "Determine if product can be sold in the specific state"
	salience 97
	when
		$policyProd : PolicyProduct()
		Policy(issueState memberOf  $policyProd.states)
	then
		result.setApprovedState(Boolean.TRUE);

end</pre>
</div>
<div>The policy has an attribute agents of the type List. We want to verify if an agent named Bill Smith is affiliated to this policy. We verify that using the contains operator. What if its the other way around? I need to determine if a given String exists within a Collection. This is exactly the issue handled in the second rule using memberof operator. The issueState is a String attribute of Policy. There is a PolicyProduct class which maintains all the valid states for a given product. The memberof operator verifies if the specified String is present in the PolicyProduct&#8217;s Collection of states.Sometimes one needs to compare Strings on the basis of the soundex algorithm. Below are two examples using the soundslike operator provided by Drools.</p>
<pre>rule "Check out the soundex function of Drools"
	# check if any insured name matches a particular pattern
	salience 96
	when
		$policy : Policy()
		exists ($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the soundex function of Drools - minor change"
	# check if any insured name matches a particular pattern with a minor variation
	salience 95
	when
		$policy : Policy()
		$coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages
	then
		result.addSoundMessage("Sound Ex Works!");

end</pre>
<div>I do not believe I need to elaborate, the example is self-explanatory. Now let&#8217;s understand the collect conditional element.</div>
<pre>rule "Check out the collect function of Drools and collect functionality diff from function"
	salience 94
	when
		$policy : Policy()
		$coverages : ArrayList(size == 2)
			from collect($coverage : Coverage(eligibility == false) from $policy.coverages)
	then
		result.setSoundexWorksCollect(Boolean.TRUE);
end</pre>
</div>
<div>Sometimes as a rules implementation we need to count the occurences of a particular event and based on the number of occurences that some action. For example, in case more than one coverages are ineligible, then take some action. To get the count we add collect conditional element after the from element and capture the objects matching the criteria in a Collection object. The Collection object size attribute is used to compare with the operational parameters.Note that unless specified otherwise the operator acting on two rules clauses is an AND operator. If we want to specify an OR operator we need to specify it explicitly. Here&#8217;s an example of an OR operator usage.</p>
<pre>rule "Check if the coverages are valid and satisfy gender, age, faceamount validation rules"
	salience 93
	#no-loop true
	when
		$policy : Policy()
		$coverage : Coverage( (faceAmount &lt; 50000 || faceAmount &gt; 250000) ||
								(	(insured.gender == "M" &amp;&amp; (insured.age &lt; 25 || insured.age &gt; 65))
									||
									(insured.gender == "F" &amp;&amp; (insured.age &lt; 18 || insured.age &gt; 65))
								)
							)
			from $policy.coverages
	then
		$coverage.setEligible(false);
end</pre>
<div>The condition defined above is as follows: If the faceamount is less than 50K or greater than 250K or a male insured whose age is greater than 65 or less than 25 or a female whose age is less than 18 or greater than 56, declare the coverage as ineligible.</div>
</div>
<div>
<pre>rule "Return value identifier sample"
	salience 92
	#no-loop true
	when
		$policy : Policy()
		$coverage1: Coverage (faceAmount == 250000, insured.gender == "F", $age : insured.age) from $policy.coverages
		$coverage2: Coverage (insured.gender == "M", insured.age == ($age+15)) from $policy.coverages
	then
		result.setRetIdentifier(Boolean.TRUE);
end</pre>
</div>
<div>Sometimes one needs to dynamically add values or compute results based on present evaluation data available within the rule condition. Drools provides the return value identifier to handle such scenarios. An example is provided below:<br />
The condition been evaluated is that a female insured has coverage face amount == 250K and age is 15 years lesser than the male insured&#8217;s age, then the RETIdentifier is set to true.Some business rules need value computations to be done as a part of the business rules condition. Drools supports such requirements too. Here are some samples of implementations using the accumulate conditional element.</p>
<pre>rule "Compute the total and average faceamount per coverage"
	salience 91
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							init (double total =0;),
							action (total += $amt;),
							reverse(total -= $amt;),
							result(total)
						)
	then
		result.setTotalFaceAmount(new Integer($total.intValue()));
end

rule "Compute the total in a simpler fashion"
	salience 90
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							sum($amt)
						)
	then
		result.setTotalFaceAmountSimp(new Integer($total.intValue()));
end

rule "Compute the average faceamount per coverage"
	salience 89
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							average($amt)
						)
	then
		result.setAverageFaceAmount(new Double($total.doubleValue()));
end</pre>
<div><span style="font-family:Consolas;line-height:18px;white-space:pre;"><span style="font-family:Georgia;line-height:19px;white-space:normal;">Basically accumulate is an advanced form of the collect conditional element. The collect conditional element allowed us to collate objects in a collection satisfying certain conditions. The accumulate conditional element moves a bit further and allows us to implement computational logic on the objects. The condtional element has four portions i.e. init, action, reverse and result. In our implementation in init we have initialized our variable, in action we are incrementing the variable with the coverage&#8217;s face amount and passing the final result to the $total variable. The value of $total variable is sent to the invoking application using the result global variable. The other two examples showcase how the sum and average functions can be used within the context of accumulate conditional element.</span><br />
</span></div>
</div>
<div>
<p>The final feature of Drools I am going to cover is query. Drools also provides you with the ability to query the input objects. Please find below a sample code for the same.</p>
<pre>query "Get Insured details for the policy"
	$policy : Policy()
	$coverages : Coverage($insured: insured ) from $policy.coverages
end

Please find below the snippet of Java code to retrieve the results.

            //Query Results
            QueryResults results = workingMemory.getQueryResults("Get Insured details for the policy");
            System.out.println( "we have " + results.size() + " insured(s)" );

            for ( Iterator it = results.iterator(); it.hasNext(); ) {
                QueryResult qResult = (QueryResult)it.next();
                Insured insured = (Insured) qResult.get( "$insured" );
                System.out.println( insured.getFirstName() + "\n" );
            }</pre>
</div>
<div>I am still not sure how in real life scenarios this feature can be utilized. That&#8217;s all from the Drools desk. The only topic left to cover is Rules flow. However I will not be covering that as it needs to be explained using a pictorial representation and I just do not have the patience.</div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=154&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/05/20/jboss-drools-defining-business-rules/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring HA-JMS on JBoss server cluster</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/04/23/configuring-ha-jms-on-jboss-server-cluster/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/04/23/configuring-ha-jms-on-jboss-server-cluster/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 14:40:47 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[Clustering]]></category>
		<category><![CDATA[HA-JMS]]></category>
		<category><![CDATA[JBoss]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=136</guid>
		<description><![CDATA[After setting up the HTTP/HTTPS configuration for JBoss server cluster, the next assignment on my table was to set up the HA-JMS on the server cluster.

My JBoss installation folder structure is as below:
JBOSS_HOME\server\all
JBOSS_HOME\server\default
JBOSS_HOME\server\minimal
The &#8220;all&#8221; folder has everything configured for HA, however to understand the process, I have set up HA JMS within default folder. Go [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=136&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div>After setting up the HTTP/HTTPS configuration for JBoss server cluster, the next assignment on my table was to set up the HA-JMS on the server cluster.</div>
<p><span id="more-136"></span></p>
<div>My JBoss installation folder structure is as below:</div>
<pre>JBOSS_HOME\server\all
JBOSS_HOME\server\default
JBOSS_HOME\server\minimal</pre>
<div>The &#8220;all&#8221; folder has everything configured for HA, however to understand the process, I have set up HA JMS within default folder. Go to the following folder JBOSS_HOME\server\default\deploy\jms</div>
<div>Remove all the files within the jms folder except jms-ra.rar. Please take a backup of these files some files might be required later. Within the default folder create a new folder named deploy-hasingleton within this folder create a sub-folder named jms. The contents of this folder will be similar to contents of the jms folder we had cleaned up earlier. The contents are as follows:</div>
<pre>Folder - jbossmq-httpil.sar
File - hsqldb-jdbc-state-service.xml
    No change from the default file except change the following tag
    &lt;depends optional-attribute-name="ConnectionManager"&gt;jboss.jca:service=DataSourceBinding,name=MySqlDS&lt;/depends&gt;
    My data source name is MySqlDS, please point to your appropriate data source name.
File - jbossmq-destinations-service.xml
    I have retained the original file please feel free alter this file to 
reflect your queues/topics.
File - jbossmq-service.xml
    No change
File - jms-ds.xml
    No change
File - jvm-il-service.xml
    No change
File - mysql-jdbc2-service.xml
    Change the following tag to point to the correct data source
    &lt;depends optional-attribute-name="ConnectionManager"&gt;jboss.jca:service=DataSourceBinding,name=MySqlDS&lt;/depends&gt;
File - uil2-service.xml
    No change</pre>
<div>Check if the JBOSS_HOME\server\default\lib has the following two jars: jbossha.jar, jgroups.jar. If not add them from the JBOSS_HOME\server\all\lib folder.</div>
<div>Open the login-config.xml file from the folder JBOSS_HOME\server\default\conf.</div>
<div>Search for the following tag:</div>
<p><span style="font-family:Consolas;line-height:18px;white-space:pre;"> &lt;!&#8211; Security domain for JBossMQ &#8211;&gt;</span></p>
<pre>    &lt;application-policy name = "jbossmq"&gt;
       &lt;authentication&gt;
          &lt;login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
             flag = "required"&gt;
             &lt;module-option name = "unauthenticatedIdentity"&gt;guest&lt;/module-option&gt;
             &lt;module-option name = "dsJndiName"&gt;java:/MySqlDS&lt;/module-option&gt;
             &lt;module-option name = "principalsQuery"&gt;SELECT PASSWD FROM JMS_USERS WHERE USERID=?&lt;/module-option&gt;
             &lt;module-option name = "rolesQuery"&gt;SELECT ROLEID, 'Roles' FROM JMS_ROLES WHERE USERID=?&lt;/module-option&gt;
          &lt;/login-module&gt;
       &lt;/authentication&gt;
    &lt;/application-policy&gt;<span>
</span></pre>
<div>And change the dsJndiName to correct data source. Ensure that the name retains java:/ portion.</div>
<div>
<div>Copy cluster-service.xml and deploy-hasingleton-service.xml in the JBOSS_HOME\server\default\deploy folder. The sample files are available in JBOSS_HOME\all\default\deploy folder. In my case both the instances are deployed on the same machine, therefore you might need to change the port numbers in the cluster-service.xml.</div>
<div>Configure your datasource. I have created mysql-ds.xml remove the hsqldb-ds.xml file. Sample files for different types of databases are available at JBOSS_HOME\docs\jca directory.</div>
<div> </div>
<div>Now start the two instances. In case, the deployment is correct, during startup of the first instance you will see the following statements in the log files: </div>
</div>
<pre>-------------------------------------------------------
GMS: address is 122.22.22.22:3576
-------------------------------------------------------
2009-04-21 17:52:58,419 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] ViewAccepted: initial members set
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.server.ClusterPartition] Starting channel
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] get nodeName
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Get current members
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Number of cluster members: 1
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Other members: 0
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Fetching state (will wait for 30000 milliseconds):<span>
</span></pre>
<div>And in the second instance startup, the following logs are<br />
created:</div>
<pre>-------------------------------------------------------
GMS: address is 122.22.22.22:3589
-------------------------------------------------------
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] ViewAccepted: initial members set
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.server.ClusterPartition] Starting channel
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] get nodeName
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Get current members
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Number of cluster members: 2
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Other members: 1
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Fetching state (will wait for 30000 milliseconds):
2009-04-21 17:55:51,811 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] setState called<span>
</span></pre>
<div><span>You can use a sample JMS client to insert messages in queue. You can verify that only one queue is created on the cluster and if the master server fails, the backup server will create the queue. The JMS client application will however need to know both the JNDI URLs i.e for the master and the slave. That intelligence will need to be built in by the developer. Please find below my JNDI client and jndi.properties file for your ready reference.</span></div>
<div><span>JNDI properties file contents:</span></div>
<pre><span>java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:2099
##java.naming.provider.url=jnp://localhost:1199
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
</span></pre>
<p>JNDI client contents:</p>
<pre>package com.jms.test;

import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.NamingException;

public class JNDIClient {

	public static void main(String[] args) {
		// create a new intial context, which loads from jndi.properties file
		javax.naming.Context ctx;
		try {
			ctx = new javax.naming.InitialContext();
			// lookup the connection factory
			javax.jms.QueueConnectionFactory factory
				= (javax.jms.QueueConnectionFactory)ctx.lookup("ConnectionFactory");

			// create a new TopicConnection for pub/sub messaging
			QueueConnection conn = factory.createQueueConnection();
			Queue queue = (Queue)ctx.lookup("queue/A");

			Session session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
			MessageProducer producer = session.createProducer(queue);
			TextMessage msg = session.createTextMessage();
			msg.setStringProperty("Name", "Cooler Dude");
			producer.send(queue, msg);

			session.close();
			conn.close();

		} catch (NamingException e) {
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}

	}
}</pre>
<div>The jndi.properties file should be placed on the JBoss server classpath.</div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/136/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=136&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/04/23/configuring-ha-jms-on-jboss-server-cluster/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring HTTP and HTTPS clustering on JBoss Server</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/04/21/configuring-http-and-https-on-jboss-server/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/04/21/configuring-http-and-https-on-jboss-server/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 15:53:46 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[Clustering]]></category>
		<category><![CDATA[HTTP/HTTPS]]></category>
		<category><![CDATA[JBoss]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=131</guid>
		<description><![CDATA[Some collegues of mine were facing problems getting the HTTP/HTTPS clustering setup done for JBoss server. Although I have no experience on working with JBoss I decided to give it a try.
Note that my development environment is Windows. The first thing I did was get hold of JBoss 4.2.2GA installable. Why this one, because this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=131&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Some collegues of mine were facing problems getting the HTTP/HTTPS clustering setup done for JBoss server. Although I have no experience on working with JBoss I decided to give it a try.</p>
<p><span id="more-131"></span>Note that my development environment is Windows. The first thing I did was get hold of JBoss 4.2.2GA installable. Why this one, because this is the one that I have!! I copied the installable twice on my machine&#8217;s D: drive, creating two JBoss homes namely D:\JBoss 4.2.2GA-1 and D:\JBoss 4.2.2GA-2. To get the clustering setup done I referred to JBoss <a title="JBoss Clustering Guide" href="http://docs.jboss.org/jbossas/guides/clusteringguide/r2/en/pdf/jboss4-clustering.pdf" target="_blank">documentation</a>. The documentation is decent and assists in getting your setup right. Instructions regarding setting up HTTP related services can be found  under section 1.5 titled &#8220;HTTP Services&#8221;.</p>
<p>First things first. Let us setup the load balancer. The load balancer is not part of the JBoss installable. JBoss uses the popular Apache Web server to assist it in achieving load balancing. The Apache web server&#8217;s jk module is used to forward all requests to the JBoss servlet container. Apache web server downloadable is available <a title="Apache Web Server Download" href="http://httpd.apache.org" target="_blank">here</a>. I have used Apache 2.0.52 and 2.0.55 for our demonstration. Per JBoss, any version in the range 2.0.x is acceptable. Next get hold of the JK module binaries from the <a title="Apache JK Module Download" href="http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/" target="_blank">site</a>. I have used mod_jk-1.2.28-httpd-2.0.52.so. Please select the jk module version compatible to your Apache server. Detailed instructions of version compatibility are available on the download <a title="JK binaries" href="http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.28/" target="_blank">page</a>. for e.g. for jk 1.2.28. Copy the JK module so file in the APACHE_HOME/modules folder.</p>
<p>Modify the APACHE_HOME/conf/httpd.conf and add the following lines at the end of the file.</p>
<pre># Include mod_jk's specific configuration file
Include conf/mod-jk.conf</pre>
<p>Create a new mod-jk.conf file and copy the file in the APACHE_HOME/conf folder. The contents of the file are as below:</p>
<pre># Load mod_jk module
LoadModule jk_module modules/mod_jk-1.2.28-httpd-2.0.52.so

# Where to find worker.properties
JkWorkersFile conf/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

#JkOptions indicate to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"

# Mount your applications
JkMount /* loadbalancer

# Add shared memory
JkShmFile logs/jk.shm</pre>
<p>Ensure that the file name is as per the installable copied in the modules folder. As per the instructions in the clustering guide, the mod-jk.conf file should have a Location tag in it. I have removed the same as it is not supported by my older Apache server. You can add the same if required. The JkMount directive in the file configures the URL that needs to be redirected. Currently it is configured to reroute all URLs; feel free to customize if required.</p>
<p>Create a new worker.properties file. Contents are as below:</p>
<pre># Define list of workers
worker.list=loadbalancer,status

# Define Node1
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10

# Define Node2
worker.node2.port=8109
worker.node2.host=localhost
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10

# Load balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer

# Status worker for managing load balancer
worker.status.type=status</pre>
<p>Note that the ports 8009 and 8109 are the JBoss AJP connector ports and not the HTTP ports. Copy the attached workers.properties in APACHE_HOME/conf folder. I have defined two nodes and am assuming both are located on the same machine.</p>
<p>The server.xml within JBOSS_HOME/server/default/deploy/jboss-web.deployer should have the following tag:</p>
<pre>    &lt;Connector port="8009" address="${jboss.bind.address}" protocol="AJP/1.3"
         emptySessionPath="true" enableLookups="false" redirectPort="8443" /&gt;<span>
</span></pre>
<p>This defines the AJP port.</p>
<p>This should be enough to get the JBOSS server running in clustered mode for HTTP.</p>
<p>I also needed to get the HTTPS setup rolling. Apparently Apache does not provide built-in SSL support. To achieve SSL support you will need to download the OpenSSL project and install it. An alternative is to get an integrated apache-openssl download from this <a title="Apache-OpenSSL download" href="http://hunter.campbus.com" target="_blank">site </a>(The site was not available , hence I used downloads from the following <a title="Apache-OpenSSL" href="http://www.thompsonbd.com/files/apache/Apache_2.0.52-Openssl_0.9.7e-Win32.zip" target="_blank">site </a>and got the openssl download from <a title="OpenSSL" href="http://www.thompsonbd.com/files/apache/Openssl-0.9.7e-Win32.zip" target="_blank">here</a>.</p>
<p>An update: The Apache <a title="Apache Download Site" href="http://httpd.apache.org/download.cgi" target="_blank">site</a> provides a Windows binary with OpenSSL built-in. So you can use that one as well.</p>
<p>I am assuming that you have created the certificate using the tomcat(jboss) server. For my testing purposes I have created a self signed certificate using the Java utility keytool. The syntax for certificate creation is as below:</p>
<pre> keytool -genkey -alias &lt;aliasName&gt; -keystore &lt;keystore name&gt;</pre>
<p>More clarity is available at this <a title="Certificate Creation" href="http://www.exampledepot.com/egs/java.security.cert/CreateCert.html" target="_blank">site</a>.</p>
<p>Go to the server.xml file located within the &lt;JBoss_home&gt;\server\default\deploy\jboss-web.deployer folder. Search for a connector tag with the following description:</p>
<pre>&lt;Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="D:\jboss-4.2.2GA-1\server\default\deploy\jboss-web.deployer\testing.keystore"
               keystorePass="testing"/&gt;</pre>
<p>Add the new attributes keystoreFile and keystorePass in the connector tag. Do the same procedure for the other server. Change the port of this server. Add a new AJP connector both the server.xml files.</p>
<pre>    &lt;Connector port="8019" address="${jboss.bind.address}" protocol="AJP/1.3"
         emptySessionPath="true" enableLookups="false" scheme="https" secure="true" redirectPort="8443" /&gt;</pre>
<p>Note that two new attributes scheme and secure have been added in the AJP connector declaration. Ensure that the port number in use do not conflict with other port numbers.</p>
<p>The Jboss servers are now ready to receive SSL requests. Now to set up the apache server for taking care of load balancing. If you have installed Apache using the URL provided above, the conf folder will have two files httpd.conf and ssl.conf. Open the conf files are check the ServerRoot and DocumentRoot paths.</p>
<p>Make sure that following lines in the httpd.conf file are uncommented.</p>
<pre>LoadModule ssl_module modules/mod_ssl.so

&lt;IfModule mod_ssl.c&gt;
    Include conf/ssl.conf
&lt;/IfModule&gt;</pre>
<p>Add the following lines at the end of the httpd.conf file</p>
<pre>&lt;VirtualHost *:80&gt;
 JkMount /* loadbalancer
&lt;/VirtualHost&gt;

# Include mod_jk's specific configuration file
Include conf/mod-jk.conf</pre>
<p>mod-jk.conf remains unchanged.</p>
<p>Unzip the OpenSSL.zip on the machine. Copy the libeay32.dll and ssleay32.dll in Windows\system32 folder of the machine.</p>
<p>The Tomcat keystore and Apache SSL certificates and keys are incompatible. They need to be converted into compatible certificate and key. For details around the conversion process refer the <a title="Certificate Conversion" href="http://techsk.blogspot.com/2009/01/exporting-tomcat-keys-to-apache-httpd.html" target="_blank">url</a>.</p>
<p>Now you should be having the pem certificate and private key. Copy the files in a suitable folder and make relevant entries for them in the ssl.conf:</p>
<pre>SSLCertificateFile /root/SSL_export/exported-pem.crt
SSLCertificateKeyFile /root/SSL_export/exported.key</pre>
<p>The intermediate certificate is not required in case of self signed certificates.</p>
<p>Add the following statement within the VirtualHost tag of the ssl.conf file</p>
<pre>JkMount /* loadbalancerSSL</pre>
<p>In ssl.conf file remove &lt;IfDefine SSL&gt; and &lt;/IfDefine&gt; tags ensure that the ServerName, DocumentRoot are pointing to the correct folders. The workers.properties file is configured to handle 4 nodes, two for HTTP requests and two for HTTPS requests.</p>
<p>Here is the updated workers.properties file.</p>
<pre># Define list of workers
worker.list=loadbalancer,loadbalancerSSL,status
#worker.list=loadbalancer,status

# Define Node1
worker.node1.port=8009
worker.node1.host=localhost
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10

# Define Node2
worker.node2.port=8109
worker.node2.host=localhost
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10

# Define Node3
worker.node3.port=8019
worker.node3.host=localhost
worker.node3.type=ajp13
worker.node3.lbfactor=1
worker.node3.cachesize=10

# Define Node2
worker.node4.port=8119
worker.node4.host=localhost
worker.node4.type=ajp13
worker.node4.lbfactor=1
worker.node4.cachesize=10

# Load balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer

# Load balancing behaviour
worker.loadbalancerSSL.type=lb
worker.loadbalancerSSL.balance_workers=node3,node4
worker.loadbalancerSSL.sticky_session=1
#worker.list=loadbalancer

# Status worker for managing load balancer
worker.status.type=status</pre>
<p>The above configuration should be enough to get the JBoss running in a clustered environment for HTTP as well as HTTPS requests.</p>
<p>This post does not cover the portion for sticky session configuration.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=131&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/04/21/configuring-http-and-https-on-jboss-server/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
		<item>
		<title>JBoss Drools &#8211; Decision Tables</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/03/28/jboss-drools-decision-tables/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/03/28/jboss-drools-decision-tables/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 14:08:01 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[JBoss Drools]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=107</guid>
		<description><![CDATA[I have been playing around with JBoss Drools(Version 4.0.7) &#8211; the open source rules engine.  JBoss supports business rules implementation using three techniques:

Decision Tables
Writing DRL file
Defining business flow using rules flow rf file

This post is going to cover the first technique for business rules definition using Drools Decision table.
Business users regularly crib about the fact [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=107&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I have been playing around with JBoss Drools(Version 4.0.7) &#8211; the open source rules engine.  JBoss supports business rules implementation using three techniques:</p>
<ol>
<li>Decision Tables</li>
<li>Writing DRL file</li>
<li>Defining business flow using rules flow rf file</li>
</ol>
<p>This post is going to cover the first technique for business rules definition using Drools Decision table.</p>
<p><span id="more-107"></span>Business users regularly crib about the fact that they need IT involvement to make changes to business rules.  One of the typical business rules implementation requirement is a decision table. Business rules can be laid out in tabular fashion and association between conditions and actions clearly defined.</p>
<p>JBoss Drools simplifies the decision table implementation approach by supporting defining decision tables in Microsoft Excel spreadsheets. For better understanding, I am going to use a simple insurance quick quote example.</p>
<p>The first thing to get started is installing Eclipse on your machine. I had Eclipse Europa version installed on my machine, hence I have to pick up the appropriate Drools Engine, Eclipse plug-in download. Next comes the procedure for setting up Drools Engine, IDE et al is available <a title="JBoss Drools Engine Documentation" href="http://downloads.jboss.com/drools/docs/4.0.7.19894.GA/html_single/index.html" target="_blank">here</a>.</p>
<p>If the Drools Eclipse plug-in setup is working fine, you should be able to use the Eclipse File &#8211;&gt; New menu to create a new Rule Project. In the newly created project named say &#8220;BusinessRules&#8221;, you will see the following folder structures:</p>
<p>BusinessRules|</p>
<p>|&#8212;&#8211; src/main/java<br />
|<br />
|&#8212;&#8211; src/main/rules</p>
<p>The src/main/java folder will hold the java class file source code and the rules files (.xls, .drl, .rf) wil be housed in src/main/rules. To create a new Decision table, select File &#8211;&gt; New &#8211;&gt; New Decision Table. The excel spreadsheet created will have the same features of a normal MS Excel spreadsheet except the rows 1 to 10 which have been created with information specific to Drools.</p>
<p>Please find below a screen shot of the decision table I prepared for an insurance quoting engine. The table decides based on the following if the applicant is eligible for insurance cover or not.</p>
<ul>
<li>Applicant&#8217;s gender</li>
<li>Applicant&#8217;s age</li>
<li>Face Amount applied for</li>
<li>Policy Issue State</li>
<li>Smoker Status</li>
<li>Whether the applicant is suffering from any adverse disease.</li>
</ul>
<div id="attachment_112" class="wp-caption aligncenter" style="width: 729px"><img class="size-full wp-image-112" title="drools-1" src="http://technicalmumbojumbo.files.wordpress.com/2009/03/drools-13.jpg?w=719&#038;h=476" alt="Drools Decision Table" width="719" height="476" /><p class="wp-caption-text">Drools Decision Table</p></div>
<p>Now that we have a sample decision tables done let&#8217;s set up the java source.</p>
<pre>package com.insure.qq;

public class QuickQuoteInputProfile {

	private String state              = null;
	private String gender             = null;
	private int age                   = 0;
	private Double faceAmount         = null;
	private boolean adverseDiagnosis  = false;
	private SmokerProfile smokingProf = null;

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Double getFaceAmount() {
		return faceAmount;
	}

	public void setFaceAmount(Double faceAmount) {
		this.faceAmount = faceAmount;
	}

	public boolean isAdverseDiagnosis() {
		return adverseDiagnosis;
	}

	public void setAdverseDiagnosis(boolean adverseDiagnosis) {
		this.adverseDiagnosis = adverseDiagnosis;
	}

	public SmokerProfile getSmokingProf() {
		return smokingProf;
	}

	public void setSmokingProf(SmokerProfile smokingProf) {
		this.smokingProf = smokingProf;
	}

}

package com.insure.qq;

public class SmokerProfile {

	private String smokerStatus = null;

	public String getSmokerStatus() {
		return smokerStatus;
	}

	public void setSmokerStatus(String smokerStatus) {
		this.smokerStatus = smokerStatus;
	}

}</pre>
<p><span>Now that we have all the code we need, let&#8217;s try and understand what have done.</span></p>
<p><span>First things first the decision table. The rows C2, C3 and C4 store specific tag information, They specify that their adjoining columns D2, D3 and D4 signify the name of the ruleset, the java class import statements and notes regarding the rules if any. A developer should not add any information in these columns besides the ones specified. The excel spread sheet does allow the developer the flexibility of defining two rule tables. We will limit ourselves to using one. Rows C6 to C10 have their own significances. C6 is used to name the rules table, C7 by itself has not information but the subsequent columns can hold two values &#8220;CONDITION&#8221; or &#8220;ACTION&#8221;. Note that the rules will not be valid unless the value in the column is one or the other. In D8 and subsequent columns, we specify the actual java class referenced in the business rule. In our case it is QuickQuoteInputProfile. Note the notation used is &lt;variable name&gt;: &lt;Java Class name&gt;. There should always be a space after the colon or else you would end up debugging some weird Drools error messages. In D9 and the following columns we specify the class attribute and the condition in which it is analyzed. D10 and following columns can be used to give business friendly names to each evaluation parameter.</span></p>
<p><span>Now let us understand how each parameter is evaluated.  Note that $param is a standard used to specify the value mentioned in the excel spreadsheet cell. </span></p>
<p><span>state in ($param) &#8211; It checks if the state requested for is part of the eligible states. Here state is an attribute of the QuickQuoteInputProfile class. Drools implicitly uses the getter method. The &#8216;in&#8217; operator usage signifies list comparison. As we want multiple String value comparisons, they are defined in the cell using a comma separator. The &#8221; &#8221; around the value specifies that the value is evaluated as a string.</span></p>
<p><span>gender == $param &#8211; String or any other primitive data type can be compared using the == operator. Putting the apostrophes around the param &#8220;$param&#8221; converts the evaluation values i.e. MALE/FEMALE into string values. </span></p>
<p><span>age &gt;= $1, age &lt;=$2 &#8211; In case we need to do a range comparison like an applicant&#8217;s age is within a given range, we can use the greater than, less than operators and use $1 and $2 as place holders. You can also use $param1 etc as the name. Also note that the comma separator between the age &gt;= $1, age &lt;= $2 is an implicit AND condition.  This can be changed. To make the condition an OR condition instead of age &gt;= $1, age &lt;= $2 put the condition </span><span>age &gt;= $1 || age &lt;= $2 and to make the condition more explicit with respect to the other conditions, enclose this condition in brackets like (</span><span>age &gt;= $1 || age &lt;= $2</span><span>).<br />
</span></p>
<p><span>quickQuoteProfile.smokingProf.smokerStatus == &#8220;$param&#8221; &#8211; It is possible that we are evaluating an object composed of objects. Drools makes it possible to navigate the entire hierarchy, using the dot(.) notation. Just ensure that all the objects are instantiated(otherwise you will get NullPointerExceptions) and that the getters will appropriate access modifiers provided.</span></p>
<p>Sometimes we need to write rules that will be triggered by the mere presence or absence of an object. For example, if SmokerProfile object exists within QuickQuoteInputProfile, then take certain action. In DRL this can be done by exists quickQuoteProfile.smokingProf(), unfortunately this fails in Excel based decision tables as a param is expected. Therefore the work around is to define the condition as exists (quickQuoteProfile.smokingProf.smokerStatus == $param) and in the rule cell write smokerStatus. The rule achieves the same effect as required.</p>
<p>Note that all rules are evaluated with an implicit AND condition between them. For example, rule 1 translates to the following condition:</p>
<blockquote><address>The policy <strong>issue state</strong> should be one of the US states &#8220;VA&#8221;, &#8220;PA&#8221;, &#8220;NY&#8221; <strong>AND</strong> applicant <strong>gender</strong> should be MALE <strong>AND</strong> applicant <strong>age</strong> is greater than 20 and less than 65 <strong>AND</strong> <strong>faceamount</strong> greater than 50K and less than 250K <strong>AND </strong>applicant is a <strong>non-smoker AND </strong>applicant does not suffer from any <strong>disease</strong> which could lead to an <strong>adverse</strong> rating.</address>
</blockquote>
<p><span>I will cover the ACTION using the following screenshot.</span></p>
<p style="text-align:center;">
<div id="attachment_117" class="wp-caption aligncenter" style="width: 710px"><img class="size-full wp-image-117" title="Drools Decision Tables - 2" src="http://technicalmumbojumbo.files.wordpress.com/2009/03/drools-2.jpg?w=700&#038;h=474" alt="Drools Decision Tables - 2" width="700" height="474" /><p class="wp-caption-text">Drools Decision Tables - 2</p></div>
<p>A typical rule will have a condition, which is evaluated and based on the evaluation an action taken. The decision/action arrived at by rules engine is conveyed to rules engine invoking client via a java object. Drools has a concept of a global variable. It can be defined as specified in row 25. In cell D25, we store the complete class name and the variable name. In our current example it is &#8220;com.insure.qq.ro.QuickQuoteResult result&#8221; where result is the variable name.  The structure of the Java class QuickQuoteResult is as below:</p>
<pre>package com.insure.qq.ro;

public class QuickQuoteResult {

	private boolean eligible = false;

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

}</pre>
<p><span>How does the decision table know that this is the class to instantiate? In cell J9, we say result.setEligible($param) and in cell C25 and D25 we specify the Variable and variable class name. Note that J9 is a cell defined under the &#8220;ACTION&#8221; column, thus translating to an action condition.(Hope this write-up is satisfactory &#8220;Novice&#8221;. Thanks for the rap on the head, must have become lazy.)<br />
</span></p>
<p><span>Now how do we run the rules engine. Create the following test class:</span></p>
<pre>package com.insure.qq.test;

import java.io.StringReader;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.drools.rule.Package;

import com.insure.qq.QuickQuoteInputProfile;
import com.insure.qq.SmokerProfile;
import com.insure.qq.ro.QuickQuoteResult;

public class QQBRETest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
        try {

        //load up the rulebase
            RuleBase ruleBase = readDecisionTable();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            QuickQuoteInputProfile input = new QuickQuoteInputProfile();
            input.setAge(21);
            input.setFaceAmount(Double.valueOf(200000));
            input.setState("VA");
            input.setGender("MALE");
            input.setAdverseDiagnosis(false);

            SmokerProfile prof = new SmokerProfile();
            prof.setSmokerStatus("Y");

            input.setSmokingProf(prof);
            QuickQuoteResult result = new QuickQuoteResult();

            workingMemory.insert(input);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(result.isEligible());

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDecisionTable() throws Exception {
		//read in the source
        final SpreadsheetCompiler converter = new SpreadsheetCompiler();
        final String drl = converter.compile( "/QuickQuoteExample.xls", InputType.XLS );
        System.out.println(drl);
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new StringReader( drl ) );
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}

}</pre>
<p>Note the usage of the WorkingMemoryFileLogger. This will create an audit file named drools-audit.log in C: drive. You can view the contents using the audit view within the Drools Eclipse perspective. In the readDecisionTable method, there is an implementation of converting the decision table spreadsheet into Drools DRL file.</p>
<p>That covers my initiation into the world of JBoss Drools Decision Tables. More drools stuff next time when write in.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/107/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=107&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/03/28/jboss-drools-decision-tables/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>

		<media:content url="http://technicalmumbojumbo.files.wordpress.com/2009/03/drools-13.jpg" medium="image">
			<media:title type="html">drools-1</media:title>
		</media:content>

		<media:content url="http://technicalmumbojumbo.files.wordpress.com/2009/03/drools-2.jpg" medium="image">
			<media:title type="html">Drools Decision Tables - 2</media:title>
		</media:content>
	</item>
		<item>
		<title>Implementing localization/internationalization(i18n) in Flex</title>
		<link>http://technicalmumbojumbo.wordpress.com/2009/02/04/implementing-localizationinternationalizationi18n-in-flex/</link>
		<comments>http://technicalmumbojumbo.wordpress.com/2009/02/04/implementing-localizationinternationalizationi18n-in-flex/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 14:25:08 +0000</pubDate>
		<dc:creator>Mr. President</dc:creator>
				<category><![CDATA[flex]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[localization]]></category>

		<guid isPermaLink="false">http://technicalmumbojumbo.wordpress.com/?p=93</guid>
		<description><![CDATA[
I spent yesterday and today morning understanding the intricacies of flex localization. There is considerable amount of Adobe documentation around the syntax and procedure for implementing localization. Unfortunately this documentation is not adequate for a first time localization implementer.



Just for reference, I continue to do my development using Flex Builder in Windows environment.
First set up [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=93&subd=technicalmumbojumbo&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><hr />
<div>I spent yesterday and today morning understanding the intricacies of flex localization. There is considerable amount of Adobe <a title="Adobe Internationalization Documentation" href="http://labs.adobe.com/wiki/index.php/Flex_3:Feature_Introductions:_Runtime_Localization" target="_blank">documentation</a> around the syntax and procedure for implementing localization. Unfortunately this documentation is not adequate for a first time localization implementer.</div>
<div><span id="more-93"></span></div>
<p></br></p>
<div>
<div>Just for reference, I continue to do my development using Flex Builder in Windows environment.</div>
<div>First set up the Flex Builder to handle internationalization(i18n). In case you have tried implementing i18n for say France using the Adobe documentation and tried running your sample, you would encounter the following error message:
</div>
<p></p>
<div><span style="font-family:Consolas;line-height:18px;white-space:pre;"><strong>&#8220;unable to open ‘C:\Program Files\Adobe\Flex Builder 3\sdks\3.1.0\frameworks\locale\fr_FR’&#8221;</strong></span></div>
<p></p>
<div>This would have been a dead-end for me but for the useful <a title="i18n tutorial" href="http://soenkerohde.com/2008/07/flex-localization/" target="_blank">blog</a> I found surfing the net.</div>
<p></p>
<div>Open a command prompt. Go to bin folder located within C:\Program Files\Adobe\Flex Builder 3\sdks\3.1.0\bin. And run  the following command on the prompt.</div>
<blockquote><p><strong>copylocale en_US fr_FR</strong></p></blockquote>
<div>This command will create fr_FR folder within C:\Program Files\Adobe\Flex Builder 3\sdks\3.1.0\frameworks\locale\. Four files namely: airframework_rb.swc, automation_rb.swc,framework_rb.swc and rpc_rb.swc are created.</div>
<div>Now let&#8217;s move on implementing the i18n functionality in Flex Builder.</div>
<div>Create a new flex project. Within the project&#8217;s src folder create a sub-folder named locale. Within locale create two folders namely en_US and fr_FR. These sub-folders will have the property file named form.properties</div>
<p>Contents of form.properties file under the en_US sub-folder<br />
firstname=First Name</p>
<p>Contents of form.properties file under the fr_FR sub-folder<br />
firstname=Prénom</p>
<div>Here&#8217;s the sample Flex Application MXML to test the i18n functionality. The MXML is self-explanatory.</div>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"&gt;
	&lt;mx:Metadata&gt;
		[ResourceBundle("form")]
	&lt;/mx:Metadata&gt;

	&lt;mx:XMLList id="localeDD"&gt;
		&lt;locale key="1" value="" /&gt;
		&lt;locale key="2" value="English" /&gt;
		&lt;locale key="3" value="French" /&gt;
	&lt;/mx:XMLList&gt;
	&lt;mx:Script&gt;
		&lt;![CDATA[
			private function setLocale():void {
				var selectedLocale:String = localeDropDown.selectedItem.@key;
				if ("1" == selectedLocale) {
					resourceManager.localeChain = ["en_US"];
				} else if ("2" == selectedLocale) {
					resourceManager.localeChain = ["en_US"];
				} else if ("3" == selectedLocale) {
					resourceManager.localeChain = ["fr_FR"];
				}
			}
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:ComboBox id="localeDropDown" x="329" y="165" editable="true" enabled="true"
		dataProvider="{localeDD}" labelField="@value" change="setLocale()"/&gt;
	&lt;mx:Label x="225" y="167" text="Select Locale" color="#FFFFFF" fontWeight="bold" fontSize="13"/&gt;
	&lt;mx:TextInput x="329" y="195"/&gt;
	&lt;mx:Label x="238" y="196" text="{resourceManager.getString('form', 'firstname')}"
		color="#FFFFFF" fontWeight="bold" fontSize="13"/&gt;

&lt;/mx:Application&gt;<span>
</span></pre>
<div>Before running the Flex application, open the Properties of the flex project. Select Flex Compiler item within the Properties window. It will provide a text input field titled &#8220;Additional Compiler Arguments&#8221;. Key in the following arguments:</div>
<blockquote><p><strong>-locale=en_US,fr_FR -source-path+=/locale/{locale}</strong></p></blockquote>
<div>Run the application, change the locale and observe the changes in the label display value.</div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/technicalmumbojumbo.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/technicalmumbojumbo.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/technicalmumbojumbo.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/technicalmumbojumbo.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/technicalmumbojumbo.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/technicalmumbojumbo.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/technicalmumbojumbo.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/technicalmumbojumbo.wordpress.com/93/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/technicalmumbojumbo.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/technicalmumbojumbo.wordpress.com/93/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=technicalmumbojumbo.wordpress.com&blog=1366554&post=93&subd=technicalmumbojumbo&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://technicalmumbojumbo.wordpress.com/2009/02/04/implementing-localizationinternationalizationi18n-in-flex/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c41774bd27fb7e396faa7400f0646298?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">Mr. President</media:title>
		</media:content>
	</item>
	</channel>
</rss>