[Documentation Index]

WSO2 Business Rules Server (BRS) User Guide

The goal of this guide is to provide guidelines to be followed in order to get familiar with both Rule Service Web UI and the procedure of exposing a rule set as a web service.

Contents

Order Approval Sample

This guide is centered on a very simple example and provides various methods of implementing that sample. The sample is shown bellow and it is only a part of a large rule set of an order processing application.

Rules

Rule 1 : An order for stocks of IBM is accepted only if the number of stocks is higher than 10.
Rule 2 : An order for stocks of SUN is accepted only if the stock prize is higher than 100 $.
Rule 3 : An order for stocks of MSFT is accepted only if the stock prize is higher than 50 $ and the number of stocks is lower than 200.
            

Facts

Above three rules are to use validating orders. For these rules , the fact is A Customer places an order. and can be captured using a Java bean as follows.

                package samples.userguide;

                /**
                * Represents the fact of a customer places an order 
                */
                public class PlaceOrder {

                String symbol;
                int quantity;
                double price;

                public String getSymbol() {
                return symbol;
                }

                public void setSymbol(String symbol) {
                this.symbol = symbol;
                }

                public int getQuantity() {
                return quantity;
                }

                public void setQuantity(int quantity) {
                this.quantity = quantity;
                }

                public double getPrice() {
                return price;
                }

                public void setPrice(double price) {
                this.price = price;
                }
                }
            

The results of the above three rule execution is either an OrderAccept or OrderReject. Those can be captured using Java beans as follows.

                package samples.userguide;

                /**
                * Order accept notification
                */
                public class OrderAccept {

                private String message;

                public String getMessage() {
                return message;
                }

                public void setMessage(String message) {
                this.message = message;
                }
                }
            
                package samples.userguide;

                /**
                * Order Reject Notification
                */
                public class OrderReject {

                private String reason;

                public String getReason() {
                return reason;
                }

                public void setReason(String reason) {
                this.reason = reason;
                }
                }
            

Using above three rules, fact and result definitions, we can now define our rules using a rule language of a rule engine. WSO2 BRS is based on the JSR 94 Java Rule Specification and uses the open source Drools rule engine as the default JSR 94 provider. Let us write the rules of our example using Drools rule language.

Drools Rule File

package OrderApproval;

import samples.userguide.OrderAccept;
import samples.userguide.OrderReject;
import samples.userguide.PlaceOrder;

rule "Order Approval Rule" dialect "mvel" no-loop true salience 4

when
$placeOrder : PlaceOrder( ( symbol == "IBM" && quantity > 10 ) || ( symbol == "SUN" && price > 100 ) || ( symbol == "MSFT" && price > 50 && quantity < 200 ) )
then

OrderAccept orderAccept = new OrderAccept();
orderAccept.setMessage("Accepted order for: "+ $placeOrder.quantity + " stocks of "+
$placeOrder.symbol +" at$ " + $placeOrder.price);
insertLogical(orderAccept);

end

rule "IBM Order Deny Rule" dialect "mvel" no-loop true salience 3

when
not ( OrderAccept())
$placeOrder : PlaceOrder( symbol == "IBM" )
then
retract($placeOrder);
OrderReject orderReject = new OrderReject();
orderReject.setReason("An Order for stocks of IBM is accepted only if the number of stocks is higher than 10.");
insertLogical(orderReject);
end

rule "SUN Order Deny Rule" dialect "mvel" no-loop true salience 2
when
not ( OrderAccept())
$placeOrder : PlaceOrder( symbol == "SUN" )
then
retract($placeOrder);
OrderReject orderReject = new OrderReject();
orderReject.setReason("An Order for stocks of SUN is accepted only if the stock price is higher than 100 $.");
insertLogical(orderReject);
end

rule "MSFT Order Deny Rule" dialect "mvel" no-loop true salience 1
when
not ( OrderAccept())
$placeOrder : PlaceOrder( symbol == "MSFT" )
then
retract($placeOrder);
OrderReject orderReject = new OrderReject();
orderReject.setReason("An Order for stocks of MSFT is accepted only if the stock price is higher than 50 $ and the number of stocks is lower than 200.");
insertLogical(orderReject);
end

            

Creating and Deploying the Rule Service

There are two ways for creating a rule service using Admin Console : Rule Service Upload and Rule Service Wizard.

Rule Service Upload

This demonstrates how to use the rule service upload UI for deploying a rule service.

Step 1 : Create a valid jar containing the java classes of facts and results defined in the Order Approval Sample presented above.

Step 2 : Creating a rule service configuration. Please refer the Configuration Guide for writing a rule service configuration. The configuration required for the sample is shown bellow. It should name as service.rsl (Rule Service Language).

<ruleService
        name="OrderApprovalService"
        xmlns="http://wso2.org/carbon/rules"
        targetNamespace="http://com.test/orderApproval">
  <ruleSet>
        <rule resourceType="regular" sourceType="file">orderApprovalRules.drl</rule>
    </ruleSet>
    <operation name="placeOrder">
        <input wrapperElementName="placeOrder" namespace="http://com.test/placeorder">
            <fact elementName="order" namespace="http://com.test/placeorder" type="samples.userguide.PlaceOrder"></fact>
        </input>
        <output wrapperElementName="placeOrderRespone" namespace="http://com.test/placeorder">
            <fact elementName="orderAccept" namespace="http://com.test/placeorder" type="samples.userguide.OrderAccept"></fact>
            <fact elementName="orderReject" namespace="http://com.test/placeorder" type="samples.userguide.OrderReject"></fact>
        </output>
    </operation>
</ruleService>

Step 4 : Organizing created three artifacts as per the figure showen bellow.

Rule Service Directory Structure

Step 5 : Make a OrderApprovalService.aar file from the above content and upload using Rule Service Upload UI

Rule Service Archive Upload UI

Rule Service Upload

Testing Sample

You can use Try-it tool for testing sample. You have to use a request similar to the one shown bellow.

                <symbol>IBM</symbol>
                <quantity>223</quantity>
                <price>14</price>

You can test each rule by changing values in the symbol, price and quantity. For the above given request , the response is shown bellow

                <brs:placeOrderResponse>
                   <brs:result>
                      <brs:OrderAccept xsi:type="ax2277:OrderAccept">
                          <ax2275:message>Accepted order for: 223 stocks of IBM at$ 14.0</ax2275:message>
                      </brs:OrderAccept>
                   </brs:result>
                </brs:placeOrderResponse>

You can also use the WSDL of the service and generate the client side code(stub) required for the service invocation. There is an option for code generation in the services management page. A client using generated stub codes is shown bellow. Codes was generated with option - Unpacks the databinding classes.

package org.wso2.carbon.samples;
import org.wso2.carbon.samples.orderApprovalService.order.OrderAccept;
import org.wso2.carbon.samples.orderApprovalService.order.PlaceOrder;
import org.wso2.carbon.samples.orderApprovalService.order.PlaceOrderE;
import org.wso2.carbon.samples.orderApprovalService.order.PlaceOrderRespone;
import org.wso2.carbon.samples.orderApprovalService.stub.OrderApprovalServiceCallbackHandler;
import org.wso2.carbon.samples.orderApprovalService.stub.OrderApprovalServiceStub;
import java.rmi.RemoteException;

public class PlaceOrderTestCase {

    public static void main(String[] args) {

        try {
            OrderApprovalServiceStub orderApprovalServiceStub = new OrderApprovalServiceStub("http://localhost:9763/services/OrderApprovalService");
            PlaceOrderE placeOrderE = new PlaceOrderE();
            PlaceOrder placeOrder = new PlaceOrder();
            placeOrder.setSymbol("IBM");
            placeOrder.setPrice(150);
            placeOrder.setQuantity(128);
            PlaceOrder[] placeOrders = new PlaceOrder[1];
            placeOrders[0] = placeOrder;
            placeOrderE.setOrder(placeOrders);

            PlaceOrderRespone placeOrderRespone = null; //new PlaceOrderRespone();
            try {
                placeOrderRespone = orderApprovalServiceStub.placeOrder(placeOrders);
            } catch (RemoteException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            OrderAccept[] orderAccepts = placeOrderRespone.getOrderAccept();
            String result = orderAccepts[0].getMessage();
            System.out.println(result);



        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Rule Service Wizard

Step 1 : Service Information. Please give the service name as OrderApprovalService2 if you have uploaded the OrderApprovalService.arr already. The description is optional. Now go to the next step

Step-1

Step 2 : Rule Set Information. There are four ways to specify the rule set or rule script. In-lined, upload, url or as a registry key. If you are going to specify as a registry key, then you have to put the rule script in the system governance registry.(Multiple scripts can be added here)

In-Lined

Step-2-Inlined

Registry

Step-2-Registry

Upload

Step-2-Uplaod

URL

Step-2-Url

Step 3 : Facts Upload. In this step, you have to upload facts and results that are used in your rule script. It should be a valid jar file. Please make a jar file from the facts and results define in section one (Multiple jars can be uploaded)

Step-3

Step 4 : Operation Summary. This displays any operation available in the service. You can uses add operation button to create a new operation

Step-4

Step 5 : Add Operation. Please put the operation name. It is mandatory. Then, defines the required input and output facts.The type is the only mandatory attribute in both input and output facts. You can use fact selector to select a type, which we have already uploaded in the input fact upload step. Please add a one fact with the type as samples.userguide.PlaceOrder and two outputs with types as samples.userguide.OrderReject and samples.userguide.OrderAccept. Now click the add button. This will bring you to the previous step (i.e. Operations Summary). Now click finish button to create and deploy the rule service.

Step-5

Fact Selector

Step-5-Fact

Testing the sample is similar to the testing procedure described in the rule service upload sample.

References