JBoss Drools Complex example

Hello All, this example give a clear idea about the jboss drools concept in writing the rules configuration files.
Advantages of a Rule Engine

  • Declarative Programming
  • Rule engines allow you to say “What to do”, not “How to do it”.

Logic and Data Separation

Your data is in your domain objects, the logic is in the rules. This is fundamentally breaking the OO coupling of data and logic, which can be an advantage or a disadvantage depending on your point of view also this approach gives Speed and Scalability, Centralization of Knowledge, Strong and Loose Coupling

Following example applies discount on product purchased based on customer from particular city.
discount_drools

following is the rule file with ext ‘.drl’

//created on: 22 Sep, 2013
package com.spark.discount.rules

//list any import classes here.
import com.spark.jbpm.drools.product.Purchase
import com.spark.jbpm.drools.person.Customer
import com.spark.jbpm.drools.product.Product

//declare any global variables here
function void displayDetails(String name,double discount) {
    System.out.println( "name: "+name+", discount: "+discount); 
}

rule "discount rule 1"
    when 
    	$customer : Customer( city == "hyderabad")
    	$purchase : Purchase(customer == $customer,qty >= 10)
    then
		$customer.setDiscount((($purchase.getQty()*$purchase.getProduct().getUnitPrice())*10)/100);
		displayDetails($customer.getName(),$customer.getDiscount());
end

rule "discount rule 2"
    when 
    	$customer : Customer( city == "bangalure")
    	$purchase : Purchase(customer == $customer,qty >= 10)
    then
		$customer.setDiscount((($purchase.getQty()*$purchase.getProduct().getUnitPrice())*25)/100);
		displayDetails($customer.getName(),$customer.getDiscount());
end

rule "discount rule 3"
    when 
    	$customer : Customer( city == "mumbai")
    	$purchase : Purchase(customer == $customer,qty >= 10)
    then
		$customer.setDiscount(($purchase.getQty()*$purchase.getProduct().getUnitPrice())*30/100);
		displayDetails($customer.getName(),$customer.getDiscount());
end

rule "discount rule 4"
    when 
    	$customer : Customer( city == "delhi")
    	$purchase : Purchase(customer == $customer,qty >= 10)
    then
		$customer.setDiscount(($purchase.getQty()*$purchase.getProduct().getUnitPrice())*40/100);
		displayDetails($customer.getName(),$customer.getDiscount());
end

rule "discount rule 5"
    when 
    	$purchase : Purchase(qty < 10 )
    then
    	System.out.println("qunatity less than 10 no discount");
end

lets code the domain objects as follows Customer.java,Product.java,Purchase.java

package com.spark.jbpm.drools.person;

public class Customer {
	private String name;
	private double discount;
	private String city;
	
	public Customer(String name, int discount) {
		super();
		this.name = name;
		this.discount = discount;
	}
	
	public Customer() {
		super();
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getDiscount() {
		return discount;
	}
	public void setDiscount(double discount) {
		this.discount = discount;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Customer)) return false;
		else 
			return this.name.equalsIgnoreCase(((Customer)obj).name);
	}

	@Override
	public int hashCode() {
		return 36*name.hashCode();
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Customer : " + name;
	}	
}
/**
 * 
 */
package com.spark.jbpm.drools.product;

/**
 * @author Sony
 * 
 */
public class Product {

	private String productCode;
	private String productName;
	private int unitPrice;
	private String name;
	private float price;

	public Product() {
		// TODO Auto-generated constructor stub
	}

	public Product(String name, float price) {
		super();
		this.name = name;
		this.price = price;
	}

	/**
	 * @return the productCode
	 */
	public String getProductCode() {
		return productCode;
	}

	/**
	 * @param productCode
	 *            the productCode to set
	 */
	public void setProductCode(String productCode) {
		this.productCode = productCode;
	}

	/**
	 * @return the productName
	 */
	public String getProductName() {
		return productName;
	}

	/**
	 * @param productName
	 *            the productName to set
	 */
	public void setProductName(String productName) {
		this.productName = productName;
	}

	/**
	 * @return the unitPrice
	 */
	public int getUnitPrice() {
		return unitPrice;
	}

	/**
	 * @param unitPrice
	 *            the unitPrice to set
	 */
	public void setUnitPrice(int unitPrice) {
		this.unitPrice = unitPrice;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the price
	 */
	public float getPrice() {
		return price;
	}

	/**
	 * @param price
	 *            the price to set
	 */
	public void setPrice(float price) {
		this.price = price;
	}

	
	@Override
	public String toString() {
		return "Product [productCode=" + productCode + ", productName="
				+ productName + ", unitPrice=" + unitPrice + "]";
	}

	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((productCode == null) ? 0 : productCode.hashCode());
		result = prime * result
				+ ((productName == null) ? 0 : productName.hashCode());
		result = prime * result + unitPrice;
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Product))
			return false;
		Product other = (Product) obj;
		if (productCode == null) {
			if (other.productCode != null)
				return false;
		} else if (!productCode.equals(other.productCode))
			return false;
		if (productName == null) {
			if (other.productName != null)
				return false;
		} else if (!productName.equals(other.productName))
			return false;
		if (unitPrice != other.unitPrice)
			return false;
		return true;
	}
}
package com.spark.jbpm.drools.product;

import com.spark.jbpm.drools.person.Customer;

public class Purchase {
	private Customer customer;
	private Product product;
	private int qty;
	
	public Purchase(Customer cus, Product prod) {
		this.customer = cus;
		this.product = prod;
	}
	
	
	public Purchase(Customer customer, Product product, int qty) {
		this.customer = customer;
		this.product = product;
		this.qty = qty;
	}


	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	public Product getProduct() {
		return product;
	}
	public void setProduct(Product product) {
		this.product = product;
	}
	
	public int getQty() {
		return qty;
	}
	public void setQty(int qty) {
		this.qty = qty;
	}	
}

following is the helper class for KnowledgeBase and StatefulKnowledgeSession


package com.spark.jbpm.drools.main;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.StatelessKnowledgeSession;

/**
 * @author Sony
 * 
 */
public class KnowledgeBaseHelperUtil {

	/**
	 * @param fileName
	 * @return {@link KnowledgeBase}
	 * @throws Exception
	 */
	public static KnowledgeBase readKnowledgeBase(String fileName)
			throws Exception {
		KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory
				.newKnowledgeBuilder();
		knowledgeBuilder.add(ResourceFactory.newClassPathResource(fileName),
				ResourceType.DRL);
		KnowledgeBuilderErrors builderErrors = knowledgeBuilder.getErrors();
		if (builderErrors.size() > 0) {
			for (KnowledgeBuilderError knowledgeBuilderError : builderErrors) {
				System.err.println(knowledgeBuilderError);
			}
			throw new IllegalArgumentException("Cant parse KnowledgeBase");
		}

		KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
		knowledgeBase.addKnowledgePackages(knowledgeBuilder
				.getKnowledgePackages());
		return knowledgeBase;
	}

	/**
	 * @param fileName
	 * @return {@link StatefulKnowledgeSession}
	 * @throws Exception
	 */
	public static StatefulKnowledgeSession getStatefulKnowledgeSession(
			String fileName) throws Exception {
		KnowledgeBase kbase = readKnowledgeBase(fileName);
		return kbase.newStatefulKnowledgeSession();
	}

	/**
	 * @param fileName
	 * @return {@link StatelessKnowledgeSession}
	 * @throws Exception
	 */
	public static StatelessKnowledgeSession getStatelessKnowledgeSession(
			String fileName) throws Exception {
		KnowledgeBase kbase = readKnowledgeBase(fileName);
		return kbase.newStatelessKnowledgeSession();
	}
}

Finally here is the main class to fire all the rules defined


package com.spark.jbpm.drools.main;

import org.drools.runtime.StatefulKnowledgeSession;

import com.spark.jbpm.drools.person.Customer;
import com.spark.jbpm.drools.product.Product;
import com.spark.jbpm.drools.product.Purchase;

/**
 * @author Sony
 * 
 */
public class MainClass {

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

		try {
			StatefulKnowledgeSession knowledgeSession = KnowledgeBaseHelperUtil
					.getStatefulKnowledgeSession("discountRules.drl");
			Customer customer = new Customer();
			customer.setName("PavanKumar Mantha");
			customer.setCity("mumbai");
			knowledgeSession.insert(customer);
			
			Product product = new Product();
			product.setUnitPrice(35000);
			knowledgeSession.insert(product);
			
			Purchase purchase = new Purchase(customer, product);
			purchase.setQty(5);
			knowledgeSession.insert(purchase);
			
			knowledgeSession.fireAllRules();
			knowledgeSession.dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

Happy Coding , Happy Drools 🙂

Advertisements

JQuery mobile and jqPlot

Hi guys, its a long time i wrote a post, these days got little busy with work. So now this is a post to integrate jquery mobile api with the jqplot to render some grap dash boards in mobile and these garph dash bords when combined with jquery mobile are compatible with all popular OS like Android and iOS .. etc. So below is the code to do it and its very self explanatory.

Following files are to be included and then start the coding part
Proj_Exp

<html lang="html">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Dynamic collapsible - jQuery Mobile Demos</title>
		<link rel="stylesheet"  href="css/jquery.mobile-1.3.1.min.css">
		<link rel="stylesheet" href="css/jqm-demos.css">
		<link class="include" rel="stylesheet" type="text/css" href="jquery.jqplot.min.css" />

		<script class="include" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
		<script src="js/index.js"></script>
		<script src="js/jquery.mobile-1.3.1.min.js"></script>

		<script>
			$(document).on("pageshow", function() {
				$.jqplot.config.enablePlugins = true;
				var s1 = [2, 6, 7, 10];
				var ticks = ['a', 'b', 'c', 'd'];

				plot1 = $.jqplot('chart1', [s1], {
					// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
					animate : !$.jqplot.use_excanvas,
					seriesDefaults : {
						renderer : $.jqplot.BarRenderer,
						pointLabels : {
							show : false
						}
					},
					axes : {
						xaxis : {
							renderer : $.jqplot.CategoryAxisRenderer
							//ticks : ticks
						}
					},
					highlighter : {
						show : false
					}
				});

				$('#chart1').bind('jqplotDataClick', function(ev, seriesIndex, pointIndex, data) {
					$('#info1').html('series: ' + seriesIndex + ', point: ' + pointIndex + ', data: ' + data);
				});

				var data = [['Heavy Industry', 12], ['Retail', 9], ['Light Industry', 14], ['Out of home', 16], ['Commuting', 7], ['Orientation', 9]];
				var plot1 = jQuery.jqplot('chart2', [data], {
					seriesDefaults : {
						// Make this a pie chart.
						renderer : jQuery.jqplot.PieRenderer,
						rendererOptions : {
							// Put data labels on the pie slices.
							// By default, labels show the percentage of the slice.
							showDataLabels : true
						}
					},
					legend : {
						show : false,
						location : 'e'
					}
				});
			});
		</script>
	</head>
	<body>

		<!-- Start of first page: #one -->
		<div data-role="page" id="one">

			<div data-role="header">
				<h1>Multi-page</h1>
			</div><!-- /header -->

			<div data-role="content" >
				<h2>Home Page</h2>

				<ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="e" data-count-theme="b">
					<li data-role="list-divider">
						Log Analysis Report
					</li>
					<li>
						<a href="index.html" data-theme="e">Bar Chart Analysis</a>
					</li>
					<li>
						<a href="index.html">Pie Chart Analysis</a>
					</li>
					<li>
						<a href="index.html">Line Chart Analysis</a>
					</li>
					<li>
						<a href="index.html">Combination Chart Analysis</a>
					</li>
				</ul>
				<div>
					<span>You Clicked: </span><span id="info1">Nothing yet</span>
				</div>

				<div id="chart1" style="margin-top:20px; margin-left:20px; width:300px; height:300px;"></div>

				<h3>Show internal pages:</h3>
				<p>
					<a href="#two" data-role="button" data-transition="slideup">Show Pie Report</a>
				</p>

			</div><!-- /content -->

			<div data-role="footer" data-theme="d">
				<h4>Page Footer</h4>
			</div><!-- /footer -->
		</div><!-- /page one -->

		<!-- Start of second page: #two -->
		<div data-role="page" id="two" data-theme="a">

			<div data-role="header">
				<h1>Pie Report</h1>
			</div><!-- /header -->

			<div data-role="content" data-theme="a">
				<h2>Pie Report</h2>
				<div id="chart2" style="margin-top:20px; margin-left:20px; width:300px; height:300px;"></div>
				<p>
					<a href="#one" data-direction="reverse" data-role="button" data-theme="b">Back to Home Page</a>
				</p>

			</div><!-- /content -->

			<div data-role="footer">
				<h4>Page Footer</h4>
			</div><!-- /footer -->
		</div><!-- /page two -->

		<!-- Don't touch this! -->
		<script class="include" type="text/javascript" src="js/jquery.jqplot.min.js"></script>

		<!-- Additional plugins go here -->

		<script class="include" type="text/javascript" src="js/jqplot.barRenderer.min.js"></script>
		<script class="include" type="text/javascript" src="js/jqplot.pieRenderer.min.js"></script>

		<script class="include" type="text/javascript" src="js/jqplot.categoryAxisRenderer.min.js"></script>
		<script class="include" type="text/javascript" src="js/jqplot.pointLabels.min.js"></script>

		<!-- End additional plugins -->

	</body>
</html>

and the following are the simulated output for the above code in the mobile.

first_screen

sec_screen

Happy Coding mobile apps 🙂

calling Oracle Coherence cache with Servlet

Hello all now then i was posted on to one of the projects in my organization which deals with large amount of data in the financial sector so the project has to be scaled in its performance and we started using “Oracle Coherence” as in memory cache, now in this post i want to discuss a small scenario how to install “Oracle Coherence R12” and use it.

What is Oracle Coherence ?
Oracle Coherence is the industry leading in-memory data grid solution that enables organizations to predictably scale mission-critical applications by providing fast access to frequently used data. As data volumes and customer expectations increase, driven by the “internet of things”, social, mobile, cloud and always-connected devices, so does the need to handle more data in real-time, offload over-burdened shared data services and provide availability guarantees.

Before starting this tutorial, you should:
1.Have access to or have installed the following software:

a. Oracle Coherence R12 for Java (or later)(Download)
b. Oracle WebLogic Server 11gR5 for Windows (Download)
c. Eclipse 3.8 (Juno) for Windows. please visit eclipse site for respective dowload.
Inside the eclipse please install the Weblogic version 11g or laterst.

Step1: Select File > New > Dynamic Web Project.
t20101

Step2:The Dynamic Runtime Module version automatically updates to 2.5 and the Configuration is set to Default Configuration for Oracle WebLogic Server 10gR3.No further configuration is needed. Click Finish.
t20105

Step3:the project structure should look as below.
prj_structure

Now its time to write the configuration and logic:
coherence-config.xml

<?xml version="1.0"?>

<!DOCTYPE cache-config SYSTEM "cache-config.dtd">

<cache-config>
	<caching-scheme-mapping>
		<cache-mapping>
			<cache-name>hello-example</cache-name>
			<scheme-name>distributed</scheme-name>
		</cache-mapping>
	</caching-scheme-mapping>

	<caching-schemes>
		<distributed-scheme>
			<scheme-name>distributed</scheme-name>
			<service-name>DistributedCache</service-name>
			<backing-map-scheme>
				<local-scheme />
			</backing-map-scheme>
			<autostart>true</autostart>
		</distributed-scheme>
	</caching-schemes>
</cache-config>

tangosol-coherence-override.xml

<?xml version='1.0'?>
 
<!DOCTYPE coherence SYSTEM "coherence.dtd">

<coherence>
	<cluster-config>
		<member-identity>
			<cluster-name>my-coherance-cluster</cluster-name>
		</member-identity>

		<multicast-listener>
			<address>224.12.1.0</address>
			<port>12100</port>
			<time-to-live>60</time-to-live>
		</multicast-listener>
	</cluster-config>

	<configurable-cache-factory-config>
		<init-params>
			<init-param>
				<param-type>java.lang.String</param-type>
				<param-value system-property="tangosol.coherence.cacheconfig">
					coherence-config.xml</param-value>
			</init-param>
		</init-params>
	</configurable-cache-factory-config>
</coherence>

coherance_put.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
	
<%@ page
	import="com.tangosol.net.CacheFactory,com.tangosol.net.NamedCache"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<%
		String key = "k2";
		String value = "Hello World!";

		CacheFactory.ensureCluster();
		NamedCache cache = CacheFactory.getCache("hello-example");

		cache.put(key, value);

	%>
</body>
</html>

coherance_get.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
	
<%@ page
	import="com.tangosol.net.CacheFactory,com.tangosol.net.NamedCache"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<%
		CacheFactory.ensureCluster();
		NamedCache cache = CacheFactory.getCache("hello-example");

		out.println((String) cache.get("k2"));
	%>
</body>
</html>

When the code is run on weblogic server and run the urls you should see the following o/p:

coherance_put

coherance_get

Happy Coherence 🙂
courtesy: http://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/coherence/obe34coherence_wls/coherence_wls_eclipse_setup/coherence_wls_eclipse_setup.htm

Will be posting when ever i get chance with new topic and content.