Tuesday, July 5, 2011

JBOSS BRMS Using JBoss Studio

1.     Initial Setup

                Before developing the BRMS rules engine project we need to install BRMS Rule engine and JBoss Developer studio as explained below.

·         Install BRMS Rule Engine

                     Use below link to install the BRMS Rule Engine

·         Install JBOSS Developer Studio

                                JBoss Developer Studio

2.     Creating BRMS Rule Project

                This section will explain how to create the BRMS rule project using JBoss Developer studio
                1. Go to File->New->Other to open the open the project wizards and select Drools Project and click on next.
2. Click on Next
               


3. Give the project Name here I given “MetaValidation”

4. Select the entire sample as mentioned in below figure which will be providing you sample code which helps you to understand.


5. Next Screen is to configure Drools Runtime environment
Select the below path in Drools Runtime Environment Path section and click OK
<BRMS Standalone home>\jboss-as-web\server\default\deploy\jboss-brms.war\WEB-INF\lib


6. Select the new Drools Runtime environment in your project.

7. After completing you will be getting Drool project as shown below figure. You could also see some sample rule flow, business rules and sample test classes.


3.     New BRMS Rule Creation

In this section I will explain how to create & test the small rules
1. Right click on src/main/rules and select the Rules Resource and click on the Next button

2. Give the Rule Name and package name and click finish which will create new business Rule file with template

Below is the new Rules template file which



Every rule will be starting with rule keyword and then name of the rule. Condition will be starting with “when” keyword and then “action” keyword to process the action. We can define the rules group or salience which prioritize the execution of rules which I will explain in my next section.
3. Will create simple rule i.e. length of member of metadata should be 6.
It represents that “Cost Center” rule which belong to rule flow-group “group1” uses the Metadata POJO object which assign into variable m and check the condition if length of member is 8 then show the message that Cost Center Metadata is valid.
m.setMessage(..) can be used to set the message and later can be accessed into Client or Test class.


4.     Small Rule Flow Creation

1. Right click on src/main/rules and select other which will open the new Flow file wizards.
2. Select the “Flow File” and click next which will move to next screen where you can give the Rule flow file name click finish which creates the new Flow File with component bar on left side.

3. Select the Rule task and place into rule drawing pane.
4. Open the Rule flow property and give the name of the Rule task and link it to with rule putting group1 on RuleFlowGroup section. If you remember we have add the rule flow group as group1 which will link rule flow with Cost Center rul.


5.     Rule Testing

1. Create new ValidationTest class to test Rules
2. Write the method readKnowledgeBase which is already available in sample or you can use below code as well

3. Use the below code to write the test client class.
package com.sample;

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.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class ValidationTest {

       public static final String DRL_URL = "Validation.drl";
       public static final String RULE_FLOW_URL = "ruleflow.rf";
       public static final void main(String[] args) {
              try {
                     // load up the knowledge base
                     ValidationTest procTest = new ValidationTest();
                     Metadata metadata = new Metadata();
                     metadata.setMember("FD1111");
                     String result = procTest.testRule(metadata);
              } catch (Throwable t) {
                     t.printStackTrace();
              }
       }
       public String testRule(Metadata metadata) {
              try {
                     // load up the knowledge base
                     KnowledgeBase kbase = readKnowledgeBase();
                     StatefulKnowledgeSession ksession = kbase
                                  .newStatefulKnowledgeSession();
                     ksession.insert(metadata);
                     KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
                                  .newFileLogger(ksession, "test");
                     // start a new process instance
                     ksession.startProcess("com.sample.ruleflow");
                     ksession.fireAllRules();
                     logger.close();
              } catch (Throwable t) {
                     t.printStackTrace();
              }
              return metadata.getMessage();
       }
       private static KnowledgeBase readKnowledgeBase() throws Exception {
              KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                           .newKnowledgeBuilder();
              kbuilder.add(ResourceFactory.newClassPathResource(DRL_URL),
                           ResourceType.DRL);
              kbuilder.add(ResourceFactory.newClassPathResource(RULE_FLOW_URL),
                           ResourceType.DRF);
              KnowledgeBuilderErrors errors = kbuilder.getErrors();
              if (errors.size() > 0) {
                     for (KnowledgeBuilderError error : errors) {
                           System.err.println(error);
                     }
                     throw new IllegalArgumentException("Could not parse knowledge.");
              }
              KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
              kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
              return kbase;
       }
}

4. Right click on the test class and run as Java Application which will provide you output on console


I can assume we have understood how to create the simple BRMS rules and test the same. In this section I would try to explore the complex rules creation. We will also learn how to prioritize & routing of rules using the rules flow. We will also see the proper use of Rule flow group.
Below are the rules which will be implementing using the BRMS
1. If Dimension of Metadata is CC then member length should be 8
2. if Dimension of Metadata is FE then member length should be 6
3. Dimension of Metadata should either be CC or FE


·         Rule Creation

Below code depicts the different rules have been created to cater the above validation. If you see carefully explored then you will find that I grouped rules in different group’s group1, group2 and group3.In this way we can instruct to the rules engine to run the group of rules separately.

#created on: Jun 29, 2011
package com.sample

#list any import classes here.
import com.sample.Metadata;

rule "Cost Center"
ruleflow-group "group1"
       when
              m: Metadata (member.length == 8 )
       then
              System.out.println("Cost Center Metadata is Valid");
              m.setMessage("Cost Center Metadata is Valid");
end

rule "Cost Center Invalid"
ruleflow-group "group1"
       when
              m: Metadata (member.length != 8 )
       then
              System.out.println("Cost Center Metadata is Invalid");
              m.setMessage("Cost Center Metadata is Invalid");
end

rule "Fund Entity"
ruleflow-group "group2"
       when
              m: Metadata (member.length == 6)
       then
              System.out.println("Fund Entity Metadata is Valid");
              m.setMessage("Fund Entity Metadata is Valid");
end

rule "Fund Entity Invalid"
ruleflow-group "group2"
       when
              m: Metadata (member.length != 6)
       then
              System.out.println("Fund Entity Metadata is Invalid");
              m.setMessage("Fund Entity Metadata is Invalid");
end


rule "Not Valid"
ruleflow-group "group3"
when
              m: Metadata (eval(true))
       then
              System.out.println("Meta Data Not Valid");
              m.setMessage("Meta Data Not Valid");
              //m.setStatus("FE");
end

·         Rule Flow Creation

We branched rule in three category i.e. CC, FE & Else. If dimension is CC then executes the CC related rules i.e. group1. if dimension is FE then execute FE related rule i.e. group2. If dimension is neither CC nor FE then execute Else part of the rule i.e. group3.
1.       Create the new rule file
2.       Select the” Start” & “End” component and add into pane
3.       Add the Gateway diverge
4.       Add 3 “Rule Task” components in the pane as mentioned in below figures.
5.    Add the Gateway Converge as mentioned in the below figure


6.       Select the Gateway diverge properties and select the Type as “OR”
7.       Click on the Constraints which will open “Edit Constraints” window

 
8.       Click on First Node Entity enter the name “FE”, Type “rule” and Dialect as “java”
9.       Enter the Metadata (dimension=”FE”) in the Textual Editor
10.       This would add the routing for FE dimension


 
11.       Similar way Edit the Constraint for CC 
 12.       Similar way Edit the Constraint for Else
  

13.       Select the Cost Center(CC) Rule Task property enter the name Cost Center and RuleFlowGroup as “group1”
14.       In the similar way add the RuleFlowGroup for FE and group2 and Else group3.
 
15.       Run the application as mentioned in Rule Testing section

Monday, January 17, 2011

Rapid Development using Model-Driven Development

Rapid Development using Model-Driven Development

Basically, MDD states that only the model of an application needs to be developed, and that the rest is automatically generated





In the context of MDD the model is the means of representing the data and the logic of the application. It can be either a graphical notation, such as UML.

Model-driven approach is use for rapid development, in which you produce a model and obtain a full application from it. The model consists of a Business Component.

The Business Component approach allows you to structure the application around business concepts. Apart from business components there will be modules like controllers, validator, calculators, etc. that you can optionally use to customize your application. It generates lot of automatic stuff, but it is flexible enough to be useful developing real life business applications.

At the end of the day you can develop applications just using simple Java classes with annotations.

Big Differences:

1. Ideal application you have to write view, model & controller ideal MVC framework but using model driven development you only need to write the model the result is less code.

2. Rapid development since only need to write the model(business component)

3. If your data structures and the business logic are likely to change frequently, then the Business Component approach is very useful since all changes can be made in the same place instead of being scattered over multiple files.

4. Productivity would increase.

5. More structured