[Documentation Index]

WSO2 BRS - Samples : Banking Service

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.

Contents

Banking Sample

This sample should be deployed in a stateful axis2 session - i.e. session scope or transport scope. This demonstrates the stateful behavior of a rule session .

Rules

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

Facts

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;
    }
}

Rule Service Configuration - service.rsl

<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>

Deploying Service

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.

Testing Sample

You can use Try-it tool with the requests similar to the following. Please as the first step do a deposit. Then after you can do withdrawing.

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();
        }

    }
}

References