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.
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.
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.
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.
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
There are two ways for creating a rule service using Admin Console : Rule Service Upload and Rule Service Wizard.
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.
Step 5 : Make a OrderApprovalService.aar file from the above content and upload using Rule Service Upload UI
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(); } } }
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 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)
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 4 : Operation Summary. This displays any operation available in the service. You can uses add operation button to create a new operation
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.
Testing the sample is similar to the testing procedure described in the rule service upload sample.