This guide demonstrates a simple banking application which uses business rules.
Please follow the User Guide before proceeding with this sample, if you have not already followed the User Guide.
Rule 1: Withdrawing is only allowed if the account balance is higher than the requested amount
Rule 2: 5% credits is given if the deposit is higher than 1000
There are two facts - A customer made a deposit request and A customer made a withdraw request.
package samples.banking; /** * Account */ public class Account { private String accountNumber; private int balance; public String getAccountNumber() { return accountNumber; } public void setAccountNumber(String accountNumber) { this.accountNumber = accountNumber; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } public void increment(int value) { balance += value; } public void decrement(int value) { balance -= value; } } package samples.banking; /** * Deposit fact */ public class Deposit { private String accountNumber; private int amount; public String getAccountNumber() { return accountNumber; } public void setAccountNumber(String accountNumber) { this.accountNumber = accountNumber; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } } package samples.banking; /** * DepositAccept facts */ public class DepositAccept { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } package samples.banking; /** * Withdraw fact */ public class Withdraw { private String accountNumber; private int amount; public String getAccountNumber() { return accountNumber; } public void setAccountNumber(String accountNumber) { this.accountNumber = accountNumber; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } } package samples.banking; /** * WithdrawAccept fact */ public class WithdrawAccept { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } package samples.banking; /** * WithdrawReject fact */ public class WithdrawReject { private String reason; public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } }
<ruleService name="BankingService" scope="transportsession" xmlns="http://wso2.org/carbon/rules" targetNamespace="http://com.test/Banking"> <ruleSet> <rule resourceType="regular" sourceType="inline"> <![CDATA[ package Banking; import samples.banking.Account; import samples.banking.Deposit; import samples.banking.DepositAccept; import samples.banking.WithdrawAccept; import samples.banking.WithdrawReject; import samples.banking.Withdraw; rule "Deposit with amount higher than 1000 in an Existing Account" dialect "mvel" no-loop true salience 6 when $deposit : Deposit( amount > 1000 ) $account : Account( accountNumber == $deposit.accountNumber ) then $account.increment($deposit.amount * 1.05); DepositAccept depositAccept = new DepositAccept(); depositAccept.setMessage("Deposit was successfully done. 5 percentage credits is given because the deposit amount is higher than 1000. Amount was : " + $deposit.amount + ". Your account balance is now : "+ $account.balance); insertLogical(depositAccept); end rule "Deposit with amount higher than 1000 in a new Account" dialect "mvel" no-loop true salience 5 when $deposit : Deposit( amount > 1000) not( Account( accountNumber == $deposit.accountNumber ) ) then Account account = new Account(); account.setAccountNumber($deposit.accountNumber); account.increment($deposit.amount * 1.05); DepositAccept depositAccept = new DepositAccept(); depositAccept.setMessage("Deposit was successfully done.5 percentage credits is given because the deposit amount is higher than 1000. Amount was : " + $deposit.amount + ". Your account balance is now : "+ account.balance); retract($deposit); insert(account); insertLogical(depositAccept); end rule "Deposit in an Existing Account" dialect "mvel" no-loop true salience 4 when $deposit : Deposit( amount <= 1000 ) $account : Account( accountNumber == $deposit.accountNumber ) then $account.increment($deposit.amount); DepositAccept depositAccept = new DepositAccept(); depositAccept.setMessage("Deposit was successfully done. 5 percentage credits would be given if the deposit amount was higher than 1000. Amount was : " + $deposit.amount + ". Your account balance is now : "+ $account.balance); insertLogical(depositAccept); end rule "Deposit in a new Account" dialect "mvel" no-loop true salience 3 when $deposit : Deposit( amount <= 1000) not( Account( accountNumber == $deposit.accountNumber) ) then Account account = new Account(); account.setAccountNumber($deposit.accountNumber); account.increment($deposit.amount); DepositAccept depositAccept = new DepositAccept(); depositAccept.setMessage("Deposit was successfully done.5 percentage credits would be given if the deposit amount was higher than 1000. Amount was : " + $deposit.amount + ". Your account balance is now : "+ account.balance); retract($deposit); insert(account); insertLogical(depositAccept); end rule "Withdrawing Allow" dialect "mvel" no-loop true salience 2 when $withdraw : Withdraw() $account : Account( accountNumber == $withdraw.accountNumber ) eval($account.balance > $withdraw.amount) then $account.decrement($withdraw.amount); WithdrawAccept withdrawAccept = new WithdrawAccept(); withdrawAccept.setMessage("Withdraw was successfully done. Amount was : " + $withdraw.amount + ". Your new account balance is : "+ $account.balance); insertLogical(withdrawAccept); end rule "Withdrawing Deny" dialect "mvel" no-loop true salience 1 when $withdraw : Withdraw() $account : Account( accountNumber == $withdraw.accountNumber ) eval($account.balance < $withdraw.amount) then WithdrawReject withdrawReject = new WithdrawReject(); withdrawReject.setReason("Withdrawing is only allowed if the account balance is higher than the requested amount. Your account balance is : "+ $account.balance); insertLogical(withdrawReject); end ]]> </rule> </ruleSet> <operation name="withDraw"> <input wrapperElementName="withDraw" namespace="http://com.test/withDraw"> <fact elementName="withDraw" namespace="http://com.test/withDraw" type="samples.banking.Withdraw"></fact> </input> <output wrapperElementName="withDrawRespone" namespace="http://com.test/withDraw"> <fact elementName="withdrawAccept" namespace="http://com.test/withDraw" type="samples.banking.WithdrawAccept"></fact> <fact elementName="withdrawReject" namespace="http://com.test/withDraw" type="samples.banking.WithdrawReject"></fact> </output> </operation> <operation name="deposit"> <input wrapperElementName="deposit" namespace="http://com.test/deposit"> <fact elementName="deposit" namespace="http://com.test/deposit" type="samples.banking.Deposit"></fact> </input> <output wrapperElementName="depositRespone" namespace="http://com.test/deposit"> <fact elementName="depositAccept" namespace="http://com.test/deposit" type="samples.banking.DepositAccept"></fact> </output> </operation> </ruleService>
You can either create an .aar file and upload or create a rule service using rule service wizard UI. Please refer User Guide for more information.
Make a Deposit
<amount>2432</amount> <accountNumber>330021vc</accountNumber>
Make a withdraw
<amount>200</amount> <accountNumber>330021vc</accountNumber>
You can also use the code generation. 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.apache.axis2.AxisFault; import org.wso2.carbon.samples.bankingService.deposit.Deposit; import org.wso2.carbon.samples.bankingService.deposit.DepositAccept; import org.wso2.carbon.samples.bankingService.deposit.DepositE; import org.wso2.carbon.samples.bankingService.stub.BankingServiceStub; import org.wso2.carbon.samples.bankingService.withdraw.*; import java.rmi.RemoteException; public class BankingServiceTestCase { public static void main(String[] args) { try { BankingServiceStub bankingServiceStub = new BankingServiceStub("http://localhost:9763/services/BankingService"); bankingServiceStub._getServiceClient().getOptions().setManageSession(true); DepositE depositRequest = new DepositE(); Deposit deposit = new Deposit(); deposit.setAccountNumber("070229x"); deposit.setAmount(1000); depositRequest.addDeposit(deposit); Deposit[] deposits = new Deposit[1]; deposits[0] = deposit; depositRequest.setDeposit(deposits); DepositAccept[] results = bankingServiceStub.deposit(deposits); String result = results[0].getMessage(); System.out.println(result); WithDrawE withDrawRequest = new WithDrawE(); Withdraw withdraw = new Withdraw(); withdraw.setAccountNumber("070229x"); withdraw.setAmount(500); Withdraw[] withdraws = new Withdraw[1]; withdraws[0] = withdraw; withDrawRequest.setWithDraw(withdraws); WithDrawRespone withDrawRespone = bankingServiceStub.withDraw(withdraws); WithdrawAccept[] withdrawAccepts = withDrawRespone.getWithdrawAccept(); WithdrawReject[] withdrawRejects = withDrawRespone.getWithdrawReject(); String resultWithDraw = withdrawAccepts[0].getMessage(); System.out.println(resultWithDraw); } catch (AxisFault axisFault) { axisFault.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }