Implementing dynamic business logic using the WebLogic Portal Rule engine

Source: Internet
Author: User
Tags filter define array execution implement variables string variable
Web| News

Brief introduction

The requirements of business applications always change with the changing trend of the business environment. Decisions are rarely immutable, and competitive pressures require flexibility in the design and implementation of business logic to quickly adapt to changing requirements. Typically, changes to the business logic must be done by the developer, and then thoroughly tested, which can be a time-consuming process. After the application's modification is complete, you need to redeploy it to the server, leaving a predetermined downtime to prevent the application from being unavailable to the user.

A better solution to this problem is to implement certain business decisions through a set of rules outside the application. These rules are not compiled into the application, but are read and applied at run time. In this way, you can change these rules without changing the code or stopping the running application.

The WebLogic portal includes a basic rule engine for WebLogic platform applications to benefit from the rules. Although the engine is not a full-featured product, we will show how it can be used with WebLogic integration Business processes (JPDs) to provide a flexible and dynamic implementation mechanism for business logic, This eliminates the need to redeploy the application only to modify the rule.

Let's take a look at the sample application that will be used in the full text, and then explain how to inject the rule engine into the WLI process to implement the business logic. We will then look more closely at the rules themselves and how to define them for business logic, and finally describe the mechanisms used to change the business rules in a running system.

Sample Application

We will develop a sample trading application as an example of using rules in business processes. The trading application is a simplified version of a financial transaction process built using the JPD business process that invokes the rule engine. The sample application uses a different collection of portfolio transactions and is divided into blocks of transactions based on a set of business-defined rules to perform, perhaps to reduce the Commission. Of course, the application given here is not complete, but it is enough to show how to use the rule engine in real-world applications. A complete source code is available for download, and the Readme file provides instructions for building and running the application.

Before we explain how to develop such an application, we first understand how it works by briefly summarizing some of the features of the portal Rule engine. This assumes that the reader is familiar with general rule techniques.

Rules engine and how it works

Figure 1 illustrates the basics of the rule engine. The engine processes the initial set of facts based on a set of rules that are obtained by the engine from the external library. The initial fact is used to populate the engine with working memory. A rule evaluates the facts in working memory and performs the corresponding action if the condition of a rule is met. Typically, a rule action adds a new fact to the working memory and repeats the process until all the rules have been applied. An optional filter is then used to select objects of a particular class to return to the caller. You can access the rule engine through the controls interface, and you can use it to set properties such as the location of the rule set file.

Figure 1: The Rule engine is an EJB wrapped by a control. The rules in the repository are applied repeatedly to the facts in working memory to get new facts. Filter working memory to return items of interest without further inference.

Invoking the rule engine from the WLI process

Let's start with the transaction business process being implemented as JPD to see how to add a call to the rule engine. To add rules to the WLI process, you can use the Rules Executor control (rule executor controls) that are provided as part of the WebLogic portal. For this example, we use only a subset of the methods and attributes provided in the control. Additional documentation about rule controls can be found in the Resources section.

It is assumed that developers use the WebLogic Workshop integrated development environment to create new process applications. You can then create a process project in the application. Because portal controls are not available by default in the process project, you need to import these controls and the EJB of the rule engine into your application. The control input and output are then inserted into the JPD. The basic steps for using the portal Rule engine in the WLI process are as follows:

Import rule engine to application:

    • Include the rule engine in your application.
    • Add the P13n_controls library to the application.

Process input and output:

    • Add variables for input and results.
    • Create a rules executor control.
    • Add a control Send and return node in the WLI process.
    • Write Java code for creating the initial data.
    • Add a process node to iterate over the results.
    • Create a rule set.

We'll discuss each of these steps in more detail later.

Include the rule engine in your application

The rule engine is included in the following file:

/weblogic81/p13n/lib/p13n_ejb.jar

To include the engine in your application, right-click the Modules folder in the Workshop integrated development environment and select Add Module. Navigate to the Jar file and select Open.

Add the P13n_controls library to the application

To make the portal rule control available in your application, right-click the Libraries folder in the Workshop integrated development environment and select Add Library. The control is located at:

</weblogic81/p13n/lib/p13n_controls.jar

Navigate to this file and click the Open button.

Add variables for input and results

The rules executor control method used here requires an array of objects as input and an iterator that returns a result. Create variables for these values in the Workshop integrated development environment so that we can create controls in the next step through the graphical user interface. To complete this task, click the Add button for the variable in data palette, type the name of the input variable, and type the Java type java.lang.object[]. Create an output variable with Java type java.util.Iterator in the same way.

Create a Rules executor control

To create a rule control, click the Add button for the control in data palette. Select the portal Controls-> Rules Executor from the menu. Type a name for the control and press the Create button.

Add a control Send and return node in the WLI process

Drag and drop the control you just created into the process to create a control node to actually invoke the rule engine. In the example, we'll use the Evaluateruleset () method of the control. From the Send Data panel, select the input variable that you created earlier for the method's input parameters. Use the Receive Data panel to select the return variable to get the result of the rule execution. Type the values for the control properties in the Property Editor window.

Write Java code for creating initial data

After creating the input variable, we have not yet assigned it a value, so we need to write code to complete the task. This variable is an array of Java objects that provide the initial facts that are entered into a rule condition. You can either create a new perform node to initialize the array, or set the value of the variable by using Source view to add code to the control send node.

Add a process node to iterate over the results

Each calculation method of the Rules executor control returns an iterator for the result. Write code that uses this value to implement an iteration of the result of the rule execution. If no filter class is specified, the iterator returns all the values in the working memory of the rule engine. This includes the original input and any values added to the working memory when the action of the rule that satisfies the condition is executed. For added objects, the iterator returns an object of the result class, which GetObject () method can return the actual object added in the rule action.

Create a rule set

Using the XML Editor, create a file with the. rls extension in the/meta-inf/data directory. Rules are usually added to the subdirectory rulesets.

Business logic Rules

We've just shown how to insert the Rule engine in a business process. Now let's look at how to take advantage of the rule engine and how to write rules that map to business rules.

A rule consists of two parts: a condition that must be true when the rule is applied, and an action to be performed when the condition is met. Therefore, to use rules in an application, designers must first define which objects and attributes are visible to the rule writer when testing the rule condition. The rules engine allows any number of methods to be invoked in one condition. This construction makes it easy to define JavaBean as the object that makes up the initial fact set, and the rules engine uses these initial facts for inference. You can use the bean's Get method to obtain the value of the conditional test.

The Java object referenced by the rule needs to be visible from the WLI process that created it and from the rules engine itself. This avoids these objects being in the same package as the process JPD, or rather, they should be created in a Java project that is part of the same application. These objects can then be referenced by the package.class tag in the rule file (. rls) and the process JPD.

In our trading example, different transactions are grouped so that they can be executed in blocks. To achieve this goal, we define two beans to represent the related objects. The first is the trade bean, which represents a single transaction order. The bean's attributes represent the share of the transaction, the number of shares, and the expected price. Any value that might be useful for determining the block to which the transaction belongs should be used as the property of the bean that has the public get method so that it is available in the rule. The second bean is the Block bean, which allows you to store all the different transactions that are clustered together according to a property. The Bean's properties include any information in the rule that can be used to determine whether the block is large enough to execute the order. These attributes can be the average price, the total dollar number of the transaction, or the total number of shares, and so on.

To implement block functionality in our applications, the first use of rules to define whether a transaction needs to execute itself is sufficient (that is, it is only a block of a single transaction), or, if not, what attributes should be used to aggregate it with other transactions to form a block. Once a transaction is clustered into the appropriate block, the rule engine is invoked for the second time to determine whether the block is complete. For example, suppose we want to get a rule like this:

    • Rule 1: Any individual transaction of 5,000 shares and above shall be executed as a block.
    • Rule 2: Transactions with the same mark ordered by the same investment manager should be brought together.
    • Rule 3: The total value of more than 000 of the block should be implemented.

It is easy to invoke a method associated with an object in a rule condition, as shown in the following example, which is the condition of rule 1:

<cr:conditions>  <greater-than-or-equal-to>    <instance-method>      <variable>        <type-alias>Beans.Trade</type-alias>      </variable>      <name>getquantity</ Name>      <!--getquantity (and any other Bean property) takes           no arguments.  If it did, they           would go        <arguments>...</arguments>      -->    </instance-method >    <literal:integer>      5000    </literal:integer>  </greater-than-or-equal-to ></cr:conditions>

In this example, if there is a trade object in our fact, then the rule engine calls its getquantity () method and compares the result with the integral type 5000. If it is greater than or equal to 5000, the condition is true.

The second part of the rule is the list of actions that are performed when the condition is met. The most common action is to create a new object and add it to the set of facts that the rule engine uses to evaluate the condition. The rule engine continues to iterate over the rule until it is impossible to draw more inferences from the facts; adding new objects to the action results in another round of conditional evaluation loops. As we will see, you can create objects of any type and define the various types that have specific meaning to your application. The trick here is that the Application designer can define a set of sufficiently rich actions to contain tasks that can be invoked by the rule writer to meet a variety of business requirements.

In our trading application example, all actions create new objects that will be added to the set of work that is used by the rule engine. Some rules add a simple string object to the collection. These objects represent the intermediate facts that are deduced from the original fact, and they can be further inferred in the rules engine, but the process JPD will not interpret them in any way. Other rules will create objects of the Beans.action class. These objects include the actual commands that the process will perform when the rule condition is met. The process JPD and support classes implement known action commands to aggregate transactions and execute block transactions. In this simple example, there are actually only two known commands: creating (and executing) orders, aggregating a transaction with the specified attributes. The action of the preceding rule 2 is to assemble using attribute symbol and manager, which is as follows:

<cr:actions>  <new-instance>    <type-alias>Beans.Action</type-alias>    < Arguments>      <literal:string>symbol, manager</literal:string>    </arguments>  </ New-instance></cr:actions>

In response to this action, the process JPD and its support classes query symbol and investment manager for the current transaction, identifying the outstanding transactions with the same symbol and investment manager, and aggregating the transactions into the same block.

After the aggregation of a transaction is completed, the rule engine is invoked again from the second rules executor control to evaluate the rule and decide whether the resulting block transaction should be executed. According to Business Rule 3, the rule is as follows:

<cr:conditions>  <greater-than >    <instance-method>      <variable>        < type-alias>beans.block</type-alias>      </variable>      <name>getAmount</name>    </instance-method>    <literal:float>      50000.00    </literal:float>  </ Greater-than ></cr:conditions><cr:actions>  <new-instance>    <type-alias> beans.action</type-alias>    <arguments>      <literal:string>create</literal:string >    </arguments>  </new-instance></cr:actions>

This time, we analyze the Beans.block object, get the amount property, and compare it to the threshold value. If the condition is met, the Create command is used to add a Beans.action object to the work set, which is the signal that the notification process executes the block order.

Let's analyze the process JPD carefully. The following code is used to invoke the control send node of the rule engine. As we can see, the node uses a rules executor control to evaluate the rule set, which returns an iterator. With its properties (not given), the control filters the results and returns only the objects of the Beans.action class. With these objects, the code extracts the action commands and executes the requested action. As mentioned earlier, if the action is to aggregate the transaction, the process will use the updated block as input to start the second call to the rule engine. A second iterative loop of the result is performed by performing the appropriate action.

public void Rulesexecutorcontrolevaluateruleset () throws exception{//Execute the Rules using facts as the input #START: Code generated-protected section-you can safely//ADD CODE above this comment. #////Input Transform//return method call This.results = Rulesexecutorcontrol.evaluateruleset (this.fact    s);  Output transform//Output assignments//#END: CODE generated-protected section-you can safely//ADD Code below this comment. #///* Iterate over the results of rules execution.         This assumes is results are filtered to return only items of the Beans.action class. The command property from the ' Action is ' expected to be either the string ' Create, ' in which case a block trade can B e executed from the discrete Trade, or it are expected to being a list of attributes describing the block t     Hat this Trade should is incorporated into. */while (reSults.hasnext ()) {String action = ((action) Results.next ()). GetCommand ();  if (Action.equals ("create")) (new Block (trade)). Execute (); Single-trade else {//Aggregate trade into a intermediate block Trade.aggr                          Egate (Blockstorage, action);  /* Call the "rules engine a second time", this is the resulting block as the only input. This is to determine if the "resulting block now meets" the criteria to execute the order.            Again, results are assumed to is filtered by the "control" to "return" only the Actions.            * * Block block = Trade.getblock ();            Object blockfacts[] = new OBJECT[1];            Blockfacts[0] = block;            Iterator blockresults = Blockrulescntl.evaluateruleset (blockfacts); while (Blockresults.hasnext ()) {action = (Action) blockresults.next ()). GetCommand ();            if (Action.equals ("create")) Block.execute (); }        }    }}

Dynamic rules

One of the features of the WebLogic portal is the Datasync feature, which allows the modified data to be redeployed to the portal application in the cluster. Because the portal Rule engine obtains its rule files from the Datasync store, the application's business rules can be changed in a running system without stopping the application. For additional information about Datasync and the Datasync Web application for updating data, see the WebLogic Portal documentation.

By default, the Datasync Web application is deployed in a regular portal application. However, our sample application is a WLI process application, so you must include Datasync in it manually. To do this in the Workshop integrated development environment, right-click the Modules folder and select Add Module. Then, select the following file:

/weblogic81/p13n/lib/datasync.war

In the cluster, the Datasync application should be deployed only to the Management server.

To illustrate how to change rules in a running application, the sample application includes two different rule files, which include optional rules for aggregating transactions into blocks. The default rule (defined in the Traderules.rls file) is described earlier, and the second collection (in Altrules.rls) defines the following rules:

    • All transactions are aggregated into blocks according to the mark.
    • Execute a block that contains 3,000 or more strands.

To see the execution of a dynamic rule, first run the sample application using the test data provided. Instead of stopping the server or redeploying the application, save the original rule directly to a new file and replace the rule file from:

/meta-inf/data/rulesets/altrules.rls

Copy to:

/meta-inf/data/rulesets/traderules.rls

Run the sample data again, and you will find that different orders are generated.

Note that you do not need to rerun the Datasync Web application to update the rule in the sample domain. This is because the sample platform domain runs in development mode. In this mode, Datasync automatically polls the/meta-inf/data directory and its subdirectories to search for changes, and the changed files are automatically redeployed to the application. In a production domain, you need to use a Web application to implement data redeployment. The recommended step is to first create a jar file for all the updated files, and the root directory of the jar file should be data. Then, use the bootstrap data feature of the Datasync Web application to redeploy the jar file that contains the new rule.

Download

You can download the source code for the sample program used in this article:sampleapp.zip (2MB)

Conclusion

When used with WLI process applications, the Portal Rules engine is a powerful tool for implementing business logic. It is easy to incorporate into the WLI process, and you can use JavaBean to evaluate rule conditions, or to extend actions that are performed as a rule evaluation result. Finally, the dynamic update capabilities provided by the Datasync feature make business logic more flexible and enable you to adapt to changing requirements without changing the Java code, so you do not need to redeploy the application.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.