J2EE-related: Java Rule Engine Integration Posted on Wednesday, August 04 @ 09:57:48 CST by joezxh |
Joe. Zhang shipping "this article is taken from starrynght's blog star moon and night. The author first introduces javarule and then provides integration of spring and business rule engine.
Rule Engine Introduction
Java rule engine is a type of inference engine, which originated from a rule-based expert system.
The Java Rule Engine separates business decisions from application code and uses predefined semantic modules to write business decisions. The Java Rule Engine accepts data input, interprets business rules, and makes business decisions based on rules. In this sense, it is an important progress of software methodology in "separation of concerns.
The JSR-94 Specification defines a standard API independent of the vendor, through which developers can use different products of the Java rule engine specification. However, it is worth noting that this specification does not enforce a unified rule definition syntax. Therefore, when you need to port an application to other Java rule engines for implementation, you may need to change the rule definition.
Rule-based Expert System (RBEs)
An expert system is a branch of artificial intelligence. It imitates human reasoning methods, uses exploratory methods for reasoning, and uses terminologies that humans can understand to explain and prove their reasoning conclusions. Expert Systems are classified into neural networks, case-based reasoning, and rule-based systems.
The rule engine is part of a rule-based expert system. In order to gain a deeper understanding of the Java rule engine, we will briefly introduce the rule-based Expert System (RBEs ).
Technical Architecture of RBEs
RBEs includes three parts: Rule Base (knodge DGE base), working memory (fact base), and rule engine (inference engine ). Their structure is as follows:
As shown in, the rule engine consists of three parts: Pattern matcher, agenda, and execution engine. Pattern matcher determines which rule to execute and when to execute the rule. Agenda manages the execution sequence of the Rule selected by patternmatcher. execution engine is responsible for executing the rule and other actions.
the inference (rule) engine of RBEs
corresponds to human thinking. The rule engine has two ways of reasoning: Forward-chaining) and induction (backward-chaining ). The explain method starts from an initial fact and constantly applies rules to draw conclusions (or execute specified actions ). The induction rule is to start from assumptions and constantly look for facts that conform to the assumptions.
rete algorithm is currently the most efficient forward-chaining inference algorithm, the drools project is an object-oriented JAVA Implementation of the Rete algorithm.
the reasoning steps of the rule engine are as follows:
1. input the initial data (fact) into the working memory.
2. Use Pattern matcher to compare Rules (rule) and data (fact ).
3. If a conflict rule exists, that is, multiple rules are activated at the same time, and conflicting rules are placed in the conflict set.
4. resolve the conflict and add the activated rules to agenda in sequence.
5. Use the rule engine to execute the rules in agenda. Repeat steps 2 to 5 until all the rules in agenda are executed.
JSR 94: Java Rule Engine API
Rule-based programming is a declarative programming technology that allows you to use tentative rules instead of procedural instructions to solve problems. The rule engine is a software module that determines how rules act on reasoning data. Rules-based programming technology is widely used in the insurance and financial services industries. The rule engine technology is particularly useful when complicated rules need to be applied to a large amount of data.
The Java Rule Engine API is defined by the javax. Rules package and is a standard enterprise-level API for accessing the rule engine. Java Rule Engine API allows customersProgramUsing a unified method to interact with the Rules Engine products of different vendors is the same as using JDBC to write a database product that is independent of the vendor to access different database products. The Java Rule Engine API includes the mechanism for creating and managing rule sets, adding, deleting, and modifying objects in working memory, and the mechanism for initializing, resetting, and executing the rule engine.
Use Java Rule Engine API
The Java Rule Engine API divides the interaction with the rule engine into two types: management activities and runtime activities. Management activities include instantiation rule engine and loading rule. Runtime activities include the operation of working memory and execution rules. If you use the Java rule engine in the j2se environment, you may needCode. On the contrary, in a J2EE environment, the management activities of the Java rule engine are part of the application server. The reference implementation of JSR 94 includes a JCA connector for obtaining a ruleserviceprovider through JNDI.
Set Rule Engine
The management activity phase of the Java rule engine starts with finding a suitable javax. Rules. ruleserviceprovider object, which is the entry for the application to access the rule engine. In the J2EE environment, you may obtain ruleserviceprovider through JNDI. Otherwise, you can use the javax. Rules. ruleserviceprovidermanager class:
Javax. Rules. ruleserviceprovidermanager class:
String implname = "org. JCP. jsr94.ri. ruleserviceprovider ";
Class. forname (implname );
Ruleserviceprovider serviceprovider = ruleserviceprovidermanager. getruleserviceprovider (implname );
Once you have the ruleserviceprovider object, you can obtain a javax. Rules. admin. ruleadministrator class. From the ruleadministrator class, you can get a ruleexecutionsetprovider, which can be known from the class name and is used to create the javax. Rules. ruleexecutionsets object. Ruleexecutionset is basically a set of rules loaded into memory and ready for execution.
The javax. Rules. Admin package contains two different ruleexecutionsetprovider classes. The ruleexecutionsetprovider class includes the method for creating ruleexecutionsets from the serializable object. Therefore, when the rule engine is on a remote server, you can still use the ruleexecutionsetprovider class. The parameters of the constructor can be passed through RMI. The other class is localruleexecutionsetprovider, which contains other methods for creating ruleexectionsets from non-serializable resources (such as Java. Io. Reader-local files. If you have a ruleserviceprovider object, you can create a ruleexectionset object from the local file rules. xml. See the following code:
Ruleadministrator admin = serviceprovider. getruleadministrator ();
Hashmap properties = new hashmap ();
Properties. Put ("name", "My Rules ");
Properties. Put ("Description", "a trivial rulebase ");
Filereader reader = new filereader ("rules. xml ");
Ruleexecutionset ruleset = NULL;
Try {
Localruleexecutionsetprovider lresp =
Admin. getlocalruleexecutionsetprovider (properties );
Ruleset = lresp. createruleexecutionset (reader, properties );
} Finally {
Reader. Close ();
}
Next, you can use ruleadministrator to register the obtained ruleexecutionset and assign it a name. During running, you can create a rulesession with the same name. This rulesession uses the named ruleexecutionset. See the following example:
Admin. registerruleexecutionset ("rules", ruleset, properties );
Execution Rule Engine
In the runtime stage, you can refer to a rulesession object. The rulesession object is basically a Rule Engine instance loaded with a specific rule set. You get a ruleruntime object from ruleserviceprovider, and then get the rulesession object from javax. Rules. ruleruntime.
Rulesession is divided into two types: stateful and stateless. They have different functions. The working memory of statefulrulesession can be saved during multiple method calls. You can add multiple objects to the working memory during multiple method calls, and then execute the engine. Then you can add more objects and execute the engine again. On the contrary, the statelessrulesession class does not save the state. to execute its executerules method, you must provide all the initial data for the working memory, execute the rule engine, and obtain a content list as the return value.
In the following example, we create a statefulrulesession instance, add two objects (one integer and one string) to the working memory, execute the rules, and then get all the content in the working memory as Java. util. list object. Finally, we call the release method to clear rulesession:
Ruleruntime runtime = RSP. getruleruntime ();
Statefulrulesession session = (statefulrulesession)
Runtime. createrulesession ("rules", properties,
Ruleruntime. stateful_session_type );
Session. addobject (New INTEGER (1 ));
Session. addobject ("A string ");
Session.exe cuterules ();
List Results = session. getobjects ();
Session. Release ();
integrated with JSR 94 product implementation
supports JSR 94 standard products to achieve both paid commercial products and free open-source projects. Currently, the most mature and powerful commercial product is the jrules of ilog, which is also one of the active promoters of the JSR 94 standard. Currently, few open-source projects support the JSR 94 specification, and only drools projects are supported. It is worth noting that Jess is not an open source project and can be used for academic research for free, but it is charged for commercial purposes.
JSR 94 product implementation
Java Rule Engine commercial products include:
L. ilog's jrules
2. blazesoft's blaze
3. rules4j
4. Java Expert System Shell (Jess)
The implementation of open-source projects includes:
L. drools Project
2. OFBiz Rule Engine (JSR 94 not supported)
3. mandarax (JSR 94 is not supported currently)
Use spring Integration
The goal of integrating the Java rule engine is to encapsulate different implementations using standard Java Rule Engine APIs to shield different product implementation details. The advantage of this is that when different rule engine products are replaced, you do not have to modify the application code.
Encapsulate jsr94 implementation
The ruleenginefacade class encapsulates the Java rule engine and uses the ruleserviceproviderurl and ruleserviceproviderimpl parameters to shield configurations of different products. The Code is as follows:
Public class ruleenginefacade {
Private ruleadministrator;
Private ruleserviceprovider;
Private localruleexecutionsetprovider rulesetprovider;
Private ruleruntime;
// Configuration parameters
Private string ruleserviceproviderurl;
Private class ruleserviceproviderimpl;
Public void setruleserviceproviderurl (string URL ){
This. ruleserviceproviderurl = URL;
}
Public void setruleserviceproviderimpl (class impl ){
This. ruleserviceproviderimpl = impl;
}
Public void Init () throws exception {
Ruleserviceprovidermanager. registerruleserviceprovider (
Ruleserviceproviderurl, ruleserviceproviderimpl );
Ruleserviceprovider = ruleserviceprovidermanager. getruleserviceprovider (ruleserviceproviderurl );
Ruleadministrator = ruleserviceprovider. getruleadministrator ();
Rulesetprovider = ruleadministrator. getlocalruleexecutionsetprovider (null );
}
Public void addruleexecutionset (string binduri, inputstream resourceasstream)
Throws exception {
Reader rulereader = new inputstreamreader (resourceasstream );
Ruleexecutionset =
Rulesetprovider. createruleexecutionset (rulereader, null );
Ruleadministrator. registerruleexecutionset (binduri, ruleexecutionset, null );
}
Public statelessrulesession getstatelessrulesession (string key)
Throws exception {
Ruleruntime = ruleserviceprovider. getruleruntime ();
Return (statelessrulesession) ruleruntime. createrulesession (Key, null, ruleruntime. stateless_session_type );
}
Public statefulrulesession getstatefulrulesession (string key)
Throws exception {
Ruleruntime = ruleserviceprovider. getruleruntime ();
Return (statefulrulesession) ruleruntime. createrulesession (
Key, null, ruleruntime. stateful_session_type );
}
Public ruleserviceprovider getruleserviceprovider (){
Return this. ruleserviceprovider;
}
}
Encapsulation rules
The rule class encapsulates specific business rules. Its input parameter rulename is the configuration file name that defines the rule and relies on the ruleenginefacade component. The Code is as follows:
Public class rule {
Private string rulename;
Private ruleenginefacade enginefacade;
Public void Init () throws exception {
Inputstream is = rule. Class. getresourceasstream (rulename );
Enginefacade. addruleexecutionset (rulename, is );
Is. Close ();
}
Public void setrulename (string name ){
This. rulename = Name;
}
Public void setenginefacade (ruleenginefacade engine ){
This. enginefacade = engine;
}
Public statelessrulesession getstatelessrulesession ()
Throws exception {
Return enginefacade. getstatelessrulesession (rulename );
}
Public statefulrulesession getstatefulerulesession ()
Throws exception {
Return enginefacade. getstatefulrulesession (rulename );
}
}
Assemble rule Components
The configuration file of the Assembly rule is as follows:
Http://drools.org/
Org. drools. jsr94.rules. ruleserviceproviderimpl
/Test/maid. DRL
Test Cases
Finally, we compile the test case with the following code:
Public class jsrtest extends testcase {
Applicationcontext CTX = NULL;
Protected void setup () throws exception {
Super. Setup ();
CTX = new filesystemxmlapplicationcontext ("testrule. xml ");
}
Public void testgetrulesession () throws exception {
Rule rule = (rule) CTX. getbean ("maid ");
Assertnotnull (rule. getstatefulerulesession ());
Assertnotnull (rule. getstatelessrulesession ());
}
Public void teststatelessrule () throws exception {
Rule rule = (rule) CTX. getbean ("maid ");
Maid = new maid (50 );
List list = new arraylist ();
List. Add (FIG );
Statelessrulesession session = rule. getstatelessrulesession ();
Session.exe cuterules (list );
Session. Release ();
}
Public void teststatefulrule () throws exception {
Rule rule = (rule) CTX. getbean ("maid ");
Maid = new maid (50 );
Statefulrulesession session = rule. getstatefulerulesession ();
Session. addobject (FIG );
Session.exe cuterules ();
Session. Release ();
}
}
Run the test case. The green bar appears and the test passes.
Rule Definition Language Transformation
Because the JSR 94 specification does not force a unified rule definition syntax, you may need to change the rule definition when porting an application to other Java rule engines for implementation, for example, the drools proprietary DRL rule language is converted to standard ruleml, And the Jess rule language is converted to ruleml. This work is generally done by the XSLT converter. "