SlideShare a Scribd company logo
1 of 36
Download to read offline
DISTRIBUTED BANKING SYSTEM USING RMI
A PROJECT REPORT
Submitted by
NARALA NAVEEN REDDY(18BCE1036)
SANGAM V V S BHARADWAJ(18BCE1248)
BACHELOR OF ENGINEERING
in
COMPUTER SCIENCE ENGINEERING
VIT UNIVERSITY: CHENNAI 600127
BONAFIDE CERTIFICATE
Certified that this project report “DISTRIBUTED BANKING SYSTEM USING
RMI” is the bonafidework of NARALA NAVEEN REDDY(18BCE1036),
SANGAM V V S BHARADWAJ(18BCE1248) who carried out the project
work under my supervision.
SIGNATURE
Prof:GAYATHRI R
School of Computer Science and Engineering
VIT University
Chennai – 600127
CONTENTS
1. ABSTRACT.
2. LITERATURE REVIEW.
3. RESEARCH GAP IN EXISTING METHODS.
4. PROPOSED ARCHITECTURE.
5. MODULES EXPLANATION.
6. SCREENSHOTS.
7. CODE.
8. CONCLUSION.
1. ABSTRACT:
The Distributed Banking System is a client-server program which is
implemented using RMI (Remote Method Invocation). The servermanages
all users’ account information. A customer can invoke the following
operations at an ATM:
● Void deposit(int acnt, int amt): This operation increases thebalance
of user account acnt by amt and returns nothing.
● Withdraw(int acnt, int amt): this operation decreases the balanceof
user account acnt by amt and returns nothing.
● Float inquiry(int acnt): this operation returns the balance ofuser
account acnt.
2. LITERATURE REVIEW:
● https://ieeexplore.ieee.org/document/4296931
(Implementation and Performance Evaluation of Socket and RMI
based Java Message Passing Systems.)
● https://ieeexplore.ieee.org/document/1592774
(Requirements for and Evaluation of RMI Protocols forScientific
Computing.)
● https://ieeexplore.ieee.org/document/8742380
(Payment system using blockchain technology.)
● https://ieeexplore.ieee.org/document/8020070
(Data processing in distributed bankingsystems.)
3. RESEARCH GAP IN EXISTING METHODS:
Before we started the project, we have checked if there were any previous
versions or models of our project that have been implemented already. We
have found out that there were some previous implementations of our
project, and that they have used the concept of RMI in distributed banking.
In the previous projects, there was no time limit for the client to login, he
could login at any time after he received his pin. This posed many security
problems, as many third party’s can access that information in this huge
time gap. So, to eliminate this problem, we have added a new concept
called session time. In our project, the user is given a specific time to login
after he receives the pin, if he doesn't login in that time frame, he must wait
till a new pin is generated, and login with that pin. With this new addition,
we plan to eliminate the above problem.
4 . PROPOSED ARCHITECTURE:
5. MODULES EXPLANATION:
In this project, we have 5 major modules, they are RMI, Client side, Server
side, Interfaces and the Exceptions. Given Below is a detailed explanation
of all five modules.
● RMI:
RMI is used to build distributed applications that provide remote
communication between Java programs provided in the package
java.rmi. In an RMI application, we write two programs, a server
program (resides on the server) and a client program (resides onthe
client). Inside the server program, a remote object is created and
reference to that object is made available for the client (using the
registry). The client program requests the remote objects on the
server and tries to invoke its methods. Following are the goals of
RMI:
● To minimize the complexity of the application.
● To preserve type safety.
● Distributed garbage collection.
● Minimize the difference between working with local andremote
objects.
● Client Side:
This side of the coding part, contains all the codes related to the
client side of the project. As stated above, the client can invoke
different operations which are then executed on the server side, the
values are returned to the client. The main code in the client side is
the ATM, which is the UI for the client to run any operation. Theclient
must login to his account with a pin, we have made sure that the pin
generated must be used within a certain timeframe, or it will not
work. A new pin is generated for every 30 seconds.
● Server Side:
This is the part of the project where the code related to the server
side is stored. This side contains codes related to the operations
called by the client. This side contains code relating to the account of
the user i.e, his username and password. It also contains the Bank
code, which contains the various cases of exceptions possible, and
on which condition they must be called. There is the transaction code
which takes care of the transactions initiated by the user. Thesession
code takes care of the initiation and the ending of each session.The
session starts when the user is logged in. The statement code takes
care of the statements made by the user.
● Exceptions:
The exceptions are used to make sure that the program ends when a
invalid input is given by the user. There are many exception codes in
our code. The InvalidAccountException is used to make sure theuser
does not enter invalid account details. The StatementException is
used to make sure the user does not enter an invalid statement.
There are many more statements available.
● Interfaces:
These are used to provide the UI for both the client and server
consoles. There are only 2 codes, one is the Server UI, and theother
is the Client UI.
These are the 5 main modules in our project, we will take a closer look at
the codes available in them in the upcoming section.
6. SCREENSHOTS:
Client side.
Server Side.
Client Details Entered.
Performing operations.
7. CODE:
1. Client:
● ATM:
package client;
import exceptions.*;
import interfaces.BankInterface;
import server.Account;
import server.Statement;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.text.SimpleDateFormat;
import java.util.Date;
//Client program, which connects to the bank using RMI andclass
methods of the remote bank object
public class ATM {
static int serverAddress, serverPort, account;
static String operation, username, password;
static long sessionID, id=0;
static double amount;
static BankInterface bank;
static Date startDate, endDate;
public static void main (String args[]) {
try {
//Parse the command line arguments into the progam
getCommandLineArguments(args);
//Set up the rmi registry and get the remote bank object from it
String name = "Bank";
Registry registry = LocateRegistry.getRegistry(serverPort);
bank = (BankInterface) registry.lookup(name);
System.out.println("n ---------------nClient Connected" +
"n n");
} catch (InvalidArgumentException ie){
ie.printStackTrace();
System.out.println(ie);
} catch (Exception e){
e.printStackTrace();
System.out.println(e);
}
double balance;
//Switch based on the operation
switch (operation){
case "login":
try {
//Login with username and password
id = bank.login(username, password);
Account acc = bank.accountDetails(id);
//Print account details
System.out.println("------------------------- nAccount
Details:n n" +
"Account Number: " +
acc.getAccountNumber() +
"nSessionID: " + id +
"nUsername: " + acc.getUserName() +
"nBalance: " + acc.getBalance() +
"n n");
System.out.println("Session active for 5 minutes");
System.out.println("Use SessionID " + id + " for all other
operations");
//Catch exceptions that can be thrown from the server
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvalidLoginException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
e.printStackTrace();
}
break;
case "deposit":
try {
//Make bank deposit and get updated balance
balance = bank.deposit(account, amount, sessionID);
System.out.println("Successfully deposited E" + amount
+ " into account " + account);
System.out.println("New balance: E" + balance);
//Catch exceptions that can be thrown from the server
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
System.out.println(e.getMessage());
}
break;
case "withdraw":
try {
//Make bank withdrawal and get updated balance
balance = bank.withdraw(account, amount, sessionID);
System.out.println("Successfully withdrew E" + amount +
" from account " + account +
"nRemaining Balance: E" + balance);
//Catch exceptions that can be thrown from the server
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
System.out.println(e.getMessage());
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}
break;
case "inquiry":
try {
//Get account details from bank
Account acc = bank.inquiry(account,sessionID);
System.out.println("------------------------- nAccount
Details:n n" +
"Account Number: " + acc.getAccountNumber() +
"nUsername: " + acc.getUserName() +
"nBalance: E" + acc.getBalance() +
"n n");
//Catch exceptions that can be thrown from the server
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
System.out.println(e.getMessage());
}
break;
case "statement":
Statement s = null;
try {
//Get statement for required dates
s = (Statement) bank.getStatement(account, startDate,
endDate, sessionID);
//format statement for printing to the window
SimpleDateFormat dateFormat = new
SimpleDateFormat("dd/MM/yyyy");
System.out.print("
---n");
System.out.println("Statement for Account " + account +
" between " +
dateFormat.format(startDate) + " and " +
dateFormat.format(endDate));
System.out.print("
---n");
System.out.println("DatetttTransaction
TypetAmountttBalance");
System.out.print("
---n");
for(Object t : s.getTransations()) {
System.out.println(t);
}
System.out.print("
---n");
//Catch exceptions that can be thrown from the server
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
System.out.println(e.getMessage());
} catch (StatementException e) {
System.out.println(e.getMessage());
}
break;
default:
//Catch all case for operation that isn't one of the above
System.out.println("Operation not supported");
break;
}
}
public static void getCommandLineArguments(String args[])throws
InvalidArgumentException{
//Makes sure server, port and operation are entered as
arguments
if(args.length < 4) {
throw new InvalidArgumentException();
}
//Parses arguments from command line
//arguments are in different places based on operation, soswitch
needed here
serverPort = Integer.parseInt(args[1]);
operation = args[2];
switch (operation){
case "login":
username = args[3];
password = args[4];
break;
case "withdraw":
case "deposit":
amount = Double.parseDouble(args[4]);
account = Integer.parseInt(args[3]);
sessionID = Long.parseLong(args[5]);
break;
case "inquiry":
account = Integer.parseInt(args[3]);
sessionID = Long.parseLong(args[4]);
break;
case "statement":
account = Integer.parseInt(args[3]);
startDate = new Date(args[4]);
endDate = new Date(args[5]);
sessionID = Long.parseLong(args[6]);
break;
}
}
}
2. Exceptions:
● InsufficientFundsException:
package exceptions;
public class InsufficientFundsException extends Exception{
public InsufficientFundsException(){
super("Insufficient Funds");
}
}
● InvalidAccountException:
package exceptions;
public class InvalidAccountException extends Exception {
public InvalidAccountException(int acnum){
super("Account with account number: " + acnum + " does
not exist");
}
}
● InvalidArgumentException:
package exceptions;
public class InvalidArgumentException extends Exception{
public InvalidArgumentException() {
super("Invalid command line arguments entered");
}
}
● InvalidLoginException:
package exceptions;
public class InvalidLoginException extends Exception {
public InvalidLoginException() {
super("Your Login Details are Invalid");
}
}
● InvalidSessionException:
package exceptions;
public class InvalidSessionException extends Exception {
public InvalidSessionException() {
super("Your session has timed out after 5 minutes of
inactivity. Please Log In again");
}
}
● StatementException:
package exceptions;
public class StatementException extends Exception {
public StatementException(String msg){
super(msg);
}
}
3. Interfaces:
● BankInterface:
package interfaces;
import exceptions.*;
import server.Account;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;
public interface BankInterface extends Remote {
long login(String username, String password) throws
RemoteException, InvalidLoginException;
double deposit(int accountnum, double amount, long
sessionID) throws RemoteException, InvalidSessionException;
double withdraw(int accountnum, double amount, long
sessionID) throws RemoteException, InvalidSessionException,
InsufficientFundsException;
Account inquiry(int accountnum, long sessionID) throws
RemoteException, InvalidSessionException;
StatementInterface getStatement(int accountnum, Date from,
Date to, long sessionID) throws RemoteException,
InvalidSessionException, StatementException;
Account accountDetails(long sessionID) throws
RemoteException, InvalidSessionException;
}
● StatementInterface:
package interfaces;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public interface StatementInterface extends Serializable {
public int getAccountnum(); // returns account number
associated with this statement
public Date getStartDate(); // returns start Dateof
StatementInterface
public Date getEndDate(); // returns end Dateof
StatementInterface
public String getAccoutName(); // returns name of account
holder
public List getTransations(); // returns list of Transaction
objects that encapsulate details about each transaction
}
4. Server:
● Account:
package server;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
//Account class, which holds user details, transactions and
balance
public class Account implements Serializable {
//Instance variables for each account object
private double balance;
private String username, password;
private int accountNumber;
private List<Transaction> transactions;
//static variable to control account numbers
private static int nextAcNum = 88769912;
public Account (String uName, String pass) {
this.transactions = new ArrayList<>();
this.username = uName;
this.password = pass;
this.accountNumber = nextAcNum;
this.balance = 0;
//increment account number, so next one will be updated
nextAcNum++;
}
//add new transactions to the account
public void addTransaction(Transaction t) {
this.transactions.add(t);
}
//getters and setters
public String getUserName() {
return username;
}
public void setUserName(String userName) {
this.username = userName;
}
public double getBalance() {
return this.balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAccountNumber() {
return this.accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
public List<Transaction> getTransactions(){
return this.transactions;
}
@Override
public String toString() {
return this.accountNumber + " " + this.balance;
}
}
● Bank:
package server;
import exceptions.*;
import interfaces.*;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
//Bank Class which implements all the methods defined in the
BankInterface
public class Bank extends UnicastRemoteObject implements
BankInterface {
private List<Account> accounts; // users accounts
private List<Session> sessions, deadSessions;
public Bank() throws RemoteException
{
super();
//set up ArrayLists and create test accounts
accounts = new ArrayList<>();
sessions = new ArrayList<>();
deadSessions = new ArrayList<>();
accounts.add(new Account("user1", "pass1"));
accounts.add(new Account("user2", "pass2"));
accounts.add(new Account("user3", "pass3"));
}
public static void main(String args[]) throws Exception {
try {
//Set up securitymanager for server, and specify path to
the policy file
System.setSecurityManager(new SecurityManager());
System.out.println("n -------------------nSecurity Manager
Set");
//Add bank to the RMI registry so it can be located by
the client
String name = "Bank";
BankInterface bank = new Bank();
Registry registry =
LocateRegistry.getRegistry(Integer.parseInt(args[0]));
registry.rebind(name, bank);
System.out.println("Bank Server Bound");
System.out.println("Server Staredn------------------- n");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public long login(String username, String password) throws
RemoteException, InvalidLoginException {
//Loop through the accounts to find the correct one for
given username and password
for(Account acc : accounts) {
if(username.equals(acc.getUserName()) &&
password.equals(acc.getPassword())){
System.out.println(">> Account " +
acc.getAccountNumber() + " logged in");
//Create a new session on Successfull login, and
return ID to the client
Session s = new Session(acc);
sessions.add(s);
return s.sessionId;
}
}
//Throw exception if login details are not valid
throw new InvalidLoginException();
}
@Override
public double deposit(int accountnum, double amount, long
sessionID) throws RemoteException, InvalidSessionException {
//Check if user session is active, based on sessionID
passed by client
if(checkSessionActive(sessionID)) {
Account account;
try {
//Get the correct account
account = getAccount(accountnum);
account.setBalance(account.getBalance() + amount);
//Create transaction object for this transaction and
add to the account
Transaction t = new Transaction(account, "Deposit");
t.setAmount(amount);
account.addTransaction(t);
System.out.println(">> E" + amount + " deposited to
account " + accountnum + "n");
//return balance to client
return account.getBalance();
} catch (InvalidAccountException e) {
e.printStackTrace();
}
}
return 0;
}
@Override
public double withdraw(int accountnum, double amount, long
sessionID) throws RemoteException,
InsufficientFundsException, InvalidSessionException {
//Check if user session is active, based on sessionID
passed by client
if(checkSessionActive(sessionID)) {
try {
//Get correct user account based on accountnum
Account account = getAccount(accountnum);
//Check if withdrawal can be made, based on account
balance
if (account.getBalance() > 0 && account.getBalance()
- amount >= 0) {
account.setBalance(account.getBalance() -
amount);
//create new Transaction and add to account
Transaction t = new Transaction(account,
"Withdrawal");
t.setAmount(amount);
account.addTransaction(t);
System.out.println(">> E" + amount + " withdrawn
from account " + accountnum + "n");
//return updated balance
return account.getBalance();
}
} catch (InvalidAccountException e) {
e.printStackTrace();
}
}
//Throw exception if account doesn't have enough money
to withdraw
throw new InsufficientFundsException();
}
@Override
public Account inquiry(int accountnum, long sessionID)
throws RemoteException, InvalidSessionException {
//Check if session is active based on sessionID that is
passed in
if(checkSessionActive(sessionID)) {
try {
//Get account and return to the client
Account account = getAccount(accountnum);
System.out.println(">> Balance requested for account
" + accountnum + "n");
return account;
} catch (InvalidAccountException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public Statement getStatement(int accountnum, Date from,
Date to, long sessionID) throws RemoteException,
InvalidSessionException, StatementException {
//Check if the session is active based on sessionID from
client
if(checkSessionActive(sessionID)) {
try {
//Get correct user account
Account account = getAccount(accountnum);
System.out.println(">> Statement requested for
account " + accountnum +
" between " + from.toString() + " " + to.toString()
+ "n");
//Create new statement using the account and the
dates passed from the client
Statement s = new Statement(account, from, to);
return s;
} catch (InvalidAccountException e) {
e.printStackTrace();
}
}
//throw exception if statement cannot be generated
throw new StatementException("Could not generate
statement for given account and dates");
}
@Override
public Account accountDetails(long sessionID) throws
InvalidSessionException {
//Get account details based on the session ID
//Each session has an associated account, so the
accounts can be retrieved based on a session
//Used on the client for looking up accounts
for(Session s:sessions){
if(s.getClientId() == sessionID){
return s.getAccount();
}
}
//Throw exception if session isn't valid
throw new InvalidSessionException();
}
private Account getAccount(int acnum) throws
InvalidAccountException{
//Loop through the accounts to find one corresponding to
account number passed from the client
//and return it
for(Account acc:accounts){
if(acc.getAccountNumber() == acnum){
return acc;
}
}
//Throw exception if account does not exist
throw new InvalidAccountException(acnum);
}
private boolean checkSessionActive(long sessID) throws
InvalidSessionException{
//Loop through the sessions
for(Session s : sessions){
//Checks if the sessionID passed from client is in the
sessions list and active
if(s.getClientId() == sessID && s.isAlive()) {
//Prints session details and returns true if session is
alive
System.out.println(">> Session " + s.getClientId() + "
running for " + s.getTimeAlive() + "s");
System.out.println(">> Time Remaining: " +
(s.getMaxSessionLength() - s.getTimeAlive()) + "s");
return true;
}
//If session is in list, but timed out, add it to
deadSessions list
//This flags timed out sessions for removeAll
//They will be removed next time this method is called
if(!s.isAlive()) {
System.out.println("n>> Cleaning up timed out
sessions");
System.out.println(">> SessionID: " + s.getClientId());
deadSessions.add(s);
}
}
System.out.println();
list
}
// cleanup dead sessions by removing them from sessions
sessions.removeAll(deadSessions);
//throw exception if sessions passed to client is not valid
throw new InvalidSessionException();
}
● Session:
package server;
import java.io.Serializable;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
//Session Object
//extends TimerTask, a thread that can be called at certaintime
intervals
//this allows the session to time to be incremented every
second, and can be cancelled after 5mins (300s)
public class Session extends TimerTask implements
Serializable{
//Instance variables for each session object
private int timeAlive;
private Timer timer;
private volatile boolean alive;
private Account account;
public long sessionId;
//static variables to specify max session time, and timer delay
private static final int MAX_SESSION_LENGTH = 60 * 5;
private static final long DELAY = 1000;
public Session(Account account) {
//generate a random 6 digit sessionID
this.sessionId = (int)(Math.random()*900000)+100000;
this.account = account;
this.alive = true;
this.timeAlive = 0;
//create timer object to allow the task to be scheduled to
run every second
this.timer = new Timer();
this.startTimer();
System.out.println(">> Session " + sessionId + "
createdn");
}
private void startTimer() {
//schedule timer to run every second
this.timer.scheduleAtFixedRate(this, new
Date(System.currentTimeMillis()), DELAY);
}
@Override
public void run() {
//increment the time the session has been alive
//updates once every second, so it represents the # of
seconds the session has been alive for
this.timeAlive++;
//if session has been alive for 5 minutes
if(this.timeAlive == MAX_SESSION_LENGTH) {
//set alive to false and cancel the timer
this.alive = false;
this.timer.cancel();
System.out.println("n --------------------------nSession " +
this.sessionId + " terminated n -------------------------- ");
System.out.println(this);
System.out.println("-------------------------- ");
}
}
//Getters and Setters
public boolean isAlive() {
return this.alive;
}
public long getClientId(){
return this.sessionId;
}
public int getTimeAlive(){
return this.timeAlive;
}
public int getMaxSessionLength(){
return MAX_SESSION_LENGTH;
}
public Account getAccount(){
return this.account;
}
@Override
public String toString() {
return "Account: " + this.account.getAccountNumber() +
"nSessionID: " +
this.sessionId +"nTime Alive: " + this.timeAlive +
"nAlive: " + this.alive;
}
}
● Statement:
package server;
import interfaces.StatementInterface;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
public class Statement implements StatementInterface,
Serializable {
//Instance variables for each Statement object
private List<Transaction> relevantTransactions;
private Date startDate, endDate;
private Account account;
public Statement(Account account, Date start, Date end){
this.relevantTransactions = new ArrayList<>();
this.account = account;
this.startDate = start;
this.endDate = end;
}
@Override
public int getAccountnum() {
return this.account.getAccountNumber();
}
@Override
public Date getStartDate() {
return this.startDate;
}
@Override
public Date getEndDate() {
return this.endDate;
}
@Override
public String getAccoutName() {
return account.getUserName();
}
@Override
public List getTransations() {
//Get all the relevantTransactions for the dates passed in
this.account.getTransactions().stream()
//filter transactions based on if the date is before the
given date or not
.filter(transactions ->
transactions.getDate().after(this.startDate) &&
transactions.getDate().before(this.endDate))
//create list from these filtered transactions
.collect(Collectors.toList())
//for each transaction in the list, add it to the
relevantTransactions list that will be returned
.forEach(date -> relevantTransactions.add(date));
return this.relevantTransactions;
}
}
● Transaction:
package server;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.text.DecimalFormat;
import java.util.Date;
//Transaction Class which tracks transaction dates, and other
transaction details
public class Transaction implements Serializable {
//Instance variables
private Date date;
private String type;
private double amount;
private Account account;
private double accBalance;
public Transaction(Account account, String type) {
this.account = account;
this.accBalance = 0;
this.type = type;
this.date = new Date(System.currentTimeMillis());
}
public Date getDate() {
return this.date;
}
public int getAccountNumber() {
return this.account.getAccountNumber();
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public double getAmount() {
return this.amount;
}
public void setAmount(double amount) {
//update transaction amount and get the new account
balance, based on withdrawal or deposit
double amt = this.account.getBalance();
this.accBalance = this.type.equals("Deposit") ?
this.accBalance = amt + this.amount : amt - this.amount;
this.amount = amount;
}
@Override
public String toString() {
//Print transaction details based on transaction type
//Date and Decimals are formatted to print nicely on the
screen
SimpleDateFormat dateFormat = new
SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
if(this.type.equals("Deposit"))
return dateFormat.format(this.date) + "t" + this.type +
"ttt" + this.amount + "tt" + df.format(this.accBalance);
else
return dateFormat.format(this.date) + "t" + this.type +
"tt" + this.amount + "tt" + df.format(this.accBalance);
}
}
8. CONCLUSION:
In this project we have used the concept of distributed systems, to create
two remote consoles, namely the client side and the server side. We have
used the concept of RMI in java, to connect the two consoles. We have
invoked operations run on the client side, and used the concept of RMI to
complete the invoked operations on the server side. While completing the
project, we understood and gained clarity on various concepts like RMI,
distributed systems, etc.
Distributed banking system using rmi project

More Related Content

What's hot

Unit 4 designing classes
Unit 4  designing classesUnit 4  designing classes
Unit 4 designing classes
gopal10scs185
 

What's hot (20)

Google App Engine
Google App EngineGoogle App Engine
Google App Engine
 
Lecture 1 (distributed systems)
Lecture 1 (distributed systems)Lecture 1 (distributed systems)
Lecture 1 (distributed systems)
 
2.communcation in distributed system
2.communcation in distributed system2.communcation in distributed system
2.communcation in distributed system
 
Message Authentication Code & HMAC
Message Authentication Code & HMACMessage Authentication Code & HMAC
Message Authentication Code & HMAC
 
Generators In Python
Generators In PythonGenerators In Python
Generators In Python
 
Computer architecture page replacement algorithms
Computer architecture page replacement algorithmsComputer architecture page replacement algorithms
Computer architecture page replacement algorithms
 
Inheritance and Interfaces
Inheritance and InterfacesInheritance and Interfaces
Inheritance and Interfaces
 
Unit 2 -Cloud Computing Architecture
Unit 2 -Cloud Computing ArchitectureUnit 2 -Cloud Computing Architecture
Unit 2 -Cloud Computing Architecture
 
Distributed Operating System,Network OS and Middle-ware.??
Distributed Operating System,Network OS and Middle-ware.??Distributed Operating System,Network OS and Middle-ware.??
Distributed Operating System,Network OS and Middle-ware.??
 
Web apps architecture
Web apps architectureWeb apps architecture
Web apps architecture
 
Hash crypto
Hash cryptoHash crypto
Hash crypto
 
Unit 4 designing classes
Unit 4  designing classesUnit 4  designing classes
Unit 4 designing classes
 
PyCharm demo
PyCharm demoPyCharm demo
PyCharm demo
 
Applet Architecture - Introducing Java Applets
Applet Architecture - Introducing Java AppletsApplet Architecture - Introducing Java Applets
Applet Architecture - Introducing Java Applets
 
Message passing in Distributed Computing Systems
Message passing in Distributed Computing SystemsMessage passing in Distributed Computing Systems
Message passing in Distributed Computing Systems
 
DeadLock in Operating-Systems
DeadLock in Operating-SystemsDeadLock in Operating-Systems
DeadLock in Operating-Systems
 
Sleeping barber problem
Sleeping barber problemSleeping barber problem
Sleeping barber problem
 
Basic communication operations - One to all Broadcast
Basic communication operations - One to all BroadcastBasic communication operations - One to all Broadcast
Basic communication operations - One to all Broadcast
 
Hash Function
Hash Function Hash Function
Hash Function
 
Elements of cache design
Elements of cache designElements of cache design
Elements of cache design
 

Similar to Distributed banking system using rmi project

Documentation
DocumentationDocumentation
Documentation
Kalyan A
 
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
ragishettyanilkumar
 
Multi Banking System
Multi Banking SystemMulti Banking System
Multi Banking System
TEJVEER SINGH
 

Similar to Distributed banking system using rmi project (20)

Software Engineering Testing & Research
Software Engineering Testing & Research Software Engineering Testing & Research
Software Engineering Testing & Research
 
BANK MANAGEMENT SYSTEM report
BANK MANAGEMENT SYSTEM reportBANK MANAGEMENT SYSTEM report
BANK MANAGEMENT SYSTEM report
 
Online banking
Online bankingOnline banking
Online banking
 
Cbse computer science (c++) class 12 board project bank managment system
Cbse computer science (c++)  class 12 board project  bank managment systemCbse computer science (c++)  class 12 board project  bank managment system
Cbse computer science (c++) class 12 board project bank managment system
 
2nd--mac ver
2nd--mac ver2nd--mac ver
2nd--mac ver
 
Documentation
DocumentationDocumentation
Documentation
 
locker presentation (1)
locker presentation (1)locker presentation (1)
locker presentation (1)
 
Banking java project
Banking java projectBanking java project
Banking java project
 
Project report
Project reportProject report
Project report
 
Online bankingppt
Online bankingpptOnline bankingppt
Online bankingppt
 
banking project
banking projectbanking project
banking project
 
ProjectReport_Subhayu
ProjectReport_SubhayuProjectReport_Subhayu
ProjectReport_Subhayu
 
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
Cbsecomputersciencecclass12boardproject bankmanagmentsystem-180703065625-conv...
 
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
PPS.pptx this ppt is for coding your problems and to do ppt for new students ...
 
Micro services from scratch - Part 1
Micro services from scratch - Part 1Micro services from scratch - Part 1
Micro services from scratch - Part 1
 
Multi Banking System
Multi Banking SystemMulti Banking System
Multi Banking System
 
Srs of bms
Srs of bmsSrs of bms
Srs of bms
 
Atm project
Atm projectAtm project
Atm project
 
java Project report online banking system
java Project report online banking systemjava Project report online banking system
java Project report online banking system
 
IRJET - Anti-Fraud ATM Security System
IRJET  - Anti-Fraud ATM Security SystemIRJET  - Anti-Fraud ATM Security System
IRJET - Anti-Fraud ATM Security System
 

Recently uploaded

1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
QucHHunhnh
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
heathfieldcps1
 
Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please Practise
AnaAcapella
 

Recently uploaded (20)

Micro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfMicro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdf
 
Towards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptxTowards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptx
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please Practise
 
Fostering Friendships - Enhancing Social Bonds in the Classroom
Fostering Friendships - Enhancing Social Bonds  in the ClassroomFostering Friendships - Enhancing Social Bonds  in the Classroom
Fostering Friendships - Enhancing Social Bonds in the Classroom
 
Spatium Project Simulation student brief
Spatium Project Simulation student briefSpatium Project Simulation student brief
Spatium Project Simulation student brief
 
How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
 

Distributed banking system using rmi project

  • 1. DISTRIBUTED BANKING SYSTEM USING RMI A PROJECT REPORT Submitted by NARALA NAVEEN REDDY(18BCE1036) SANGAM V V S BHARADWAJ(18BCE1248) BACHELOR OF ENGINEERING in COMPUTER SCIENCE ENGINEERING VIT UNIVERSITY: CHENNAI 600127
  • 2. BONAFIDE CERTIFICATE Certified that this project report “DISTRIBUTED BANKING SYSTEM USING RMI” is the bonafidework of NARALA NAVEEN REDDY(18BCE1036), SANGAM V V S BHARADWAJ(18BCE1248) who carried out the project work under my supervision. SIGNATURE Prof:GAYATHRI R School of Computer Science and Engineering VIT University Chennai – 600127
  • 3. CONTENTS 1. ABSTRACT. 2. LITERATURE REVIEW. 3. RESEARCH GAP IN EXISTING METHODS. 4. PROPOSED ARCHITECTURE. 5. MODULES EXPLANATION. 6. SCREENSHOTS. 7. CODE. 8. CONCLUSION. 1. ABSTRACT: The Distributed Banking System is a client-server program which is implemented using RMI (Remote Method Invocation). The servermanages all users’ account information. A customer can invoke the following operations at an ATM: ● Void deposit(int acnt, int amt): This operation increases thebalance of user account acnt by amt and returns nothing. ● Withdraw(int acnt, int amt): this operation decreases the balanceof user account acnt by amt and returns nothing. ● Float inquiry(int acnt): this operation returns the balance ofuser account acnt.
  • 4. 2. LITERATURE REVIEW: ● https://ieeexplore.ieee.org/document/4296931 (Implementation and Performance Evaluation of Socket and RMI based Java Message Passing Systems.) ● https://ieeexplore.ieee.org/document/1592774 (Requirements for and Evaluation of RMI Protocols forScientific Computing.) ● https://ieeexplore.ieee.org/document/8742380 (Payment system using blockchain technology.) ● https://ieeexplore.ieee.org/document/8020070 (Data processing in distributed bankingsystems.) 3. RESEARCH GAP IN EXISTING METHODS: Before we started the project, we have checked if there were any previous versions or models of our project that have been implemented already. We have found out that there were some previous implementations of our project, and that they have used the concept of RMI in distributed banking. In the previous projects, there was no time limit for the client to login, he could login at any time after he received his pin. This posed many security problems, as many third party’s can access that information in this huge time gap. So, to eliminate this problem, we have added a new concept called session time. In our project, the user is given a specific time to login after he receives the pin, if he doesn't login in that time frame, he must wait till a new pin is generated, and login with that pin. With this new addition, we plan to eliminate the above problem.
  • 5. 4 . PROPOSED ARCHITECTURE:
  • 6. 5. MODULES EXPLANATION: In this project, we have 5 major modules, they are RMI, Client side, Server side, Interfaces and the Exceptions. Given Below is a detailed explanation of all five modules. ● RMI: RMI is used to build distributed applications that provide remote communication between Java programs provided in the package java.rmi. In an RMI application, we write two programs, a server program (resides on the server) and a client program (resides onthe client). Inside the server program, a remote object is created and reference to that object is made available for the client (using the registry). The client program requests the remote objects on the server and tries to invoke its methods. Following are the goals of RMI: ● To minimize the complexity of the application. ● To preserve type safety. ● Distributed garbage collection. ● Minimize the difference between working with local andremote objects. ● Client Side: This side of the coding part, contains all the codes related to the client side of the project. As stated above, the client can invoke different operations which are then executed on the server side, the values are returned to the client. The main code in the client side is the ATM, which is the UI for the client to run any operation. Theclient must login to his account with a pin, we have made sure that the pin generated must be used within a certain timeframe, or it will not work. A new pin is generated for every 30 seconds.
  • 7. ● Server Side: This is the part of the project where the code related to the server side is stored. This side contains codes related to the operations called by the client. This side contains code relating to the account of the user i.e, his username and password. It also contains the Bank code, which contains the various cases of exceptions possible, and on which condition they must be called. There is the transaction code which takes care of the transactions initiated by the user. Thesession code takes care of the initiation and the ending of each session.The session starts when the user is logged in. The statement code takes care of the statements made by the user. ● Exceptions: The exceptions are used to make sure that the program ends when a invalid input is given by the user. There are many exception codes in our code. The InvalidAccountException is used to make sure theuser does not enter invalid account details. The StatementException is used to make sure the user does not enter an invalid statement. There are many more statements available. ● Interfaces: These are used to provide the UI for both the client and server consoles. There are only 2 codes, one is the Server UI, and theother is the Client UI. These are the 5 main modules in our project, we will take a closer look at the codes available in them in the upcoming section.
  • 10. 7. CODE: 1. Client: ● ATM: package client; import exceptions.*; import interfaces.BankInterface; import server.Account; import server.Statement; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.text.SimpleDateFormat; import java.util.Date; //Client program, which connects to the bank using RMI andclass methods of the remote bank object public class ATM { static int serverAddress, serverPort, account; static String operation, username, password; static long sessionID, id=0; static double amount; static BankInterface bank; static Date startDate, endDate; public static void main (String args[]) { try { //Parse the command line arguments into the progam getCommandLineArguments(args); //Set up the rmi registry and get the remote bank object from it String name = "Bank"; Registry registry = LocateRegistry.getRegistry(serverPort); bank = (BankInterface) registry.lookup(name);
  • 11. System.out.println("n ---------------nClient Connected" + "n n"); } catch (InvalidArgumentException ie){ ie.printStackTrace(); System.out.println(ie); } catch (Exception e){ e.printStackTrace(); System.out.println(e); } double balance; //Switch based on the operation switch (operation){ case "login": try { //Login with username and password id = bank.login(username, password); Account acc = bank.accountDetails(id); //Print account details System.out.println("------------------------- nAccount Details:n n" + "Account Number: " + acc.getAccountNumber() + "nSessionID: " + id + "nUsername: " + acc.getUserName() + "nBalance: " + acc.getBalance() + "n n"); System.out.println("Session active for 5 minutes"); System.out.println("Use SessionID " + id + " for all other operations"); //Catch exceptions that can be thrown from the server } catch (RemoteException e) { e.printStackTrace(); } catch (InvalidLoginException e) { e.printStackTrace();
  • 12. } catch (InvalidSessionException e) { e.printStackTrace(); } break; case "deposit": try { //Make bank deposit and get updated balance balance = bank.deposit(account, amount, sessionID); System.out.println("Successfully deposited E" + amount + " into account " + account); System.out.println("New balance: E" + balance); //Catch exceptions that can be thrown from the server } catch (RemoteException e) { e.printStackTrace(); } catch (InvalidSessionException e) { System.out.println(e.getMessage()); } break; case "withdraw": try { //Make bank withdrawal and get updated balance balance = bank.withdraw(account, amount, sessionID); System.out.println("Successfully withdrew E" + amount + " from account " + account + "nRemaining Balance: E" + balance); //Catch exceptions that can be thrown from the server } catch (RemoteException e) { e.printStackTrace(); } catch (InvalidSessionException e) { System.out.println(e.getMessage()); } catch (InsufficientFundsException e) { System.out.println(e.getMessage()); }
  • 13. break; case "inquiry": try { //Get account details from bank Account acc = bank.inquiry(account,sessionID); System.out.println("------------------------- nAccount Details:n n" + "Account Number: " + acc.getAccountNumber() + "nUsername: " + acc.getUserName() + "nBalance: E" + acc.getBalance() + "n n"); //Catch exceptions that can be thrown from the server } catch (RemoteException e) { e.printStackTrace(); } catch (InvalidSessionException e) { System.out.println(e.getMessage()); } break; case "statement": Statement s = null; try { //Get statement for required dates s = (Statement) bank.getStatement(account, startDate, endDate, sessionID); //format statement for printing to the window SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); System.out.print(" ---n"); System.out.println("Statement for Account " + account + " between " +
  • 14. dateFormat.format(startDate) + " and " + dateFormat.format(endDate)); System.out.print(" ---n"); System.out.println("DatetttTransaction TypetAmountttBalance"); System.out.print(" ---n"); for(Object t : s.getTransations()) { System.out.println(t); } System.out.print(" ---n"); //Catch exceptions that can be thrown from the server } catch (RemoteException e) { e.printStackTrace(); } catch (InvalidSessionException e) { System.out.println(e.getMessage()); } catch (StatementException e) { System.out.println(e.getMessage()); } break; default: //Catch all case for operation that isn't one of the above System.out.println("Operation not supported"); break; } }
  • 15. public static void getCommandLineArguments(String args[])throws InvalidArgumentException{ //Makes sure server, port and operation are entered as arguments if(args.length < 4) { throw new InvalidArgumentException(); } //Parses arguments from command line //arguments are in different places based on operation, soswitch needed here serverPort = Integer.parseInt(args[1]); operation = args[2]; switch (operation){ case "login": username = args[3]; password = args[4]; break; case "withdraw": case "deposit": amount = Double.parseDouble(args[4]); account = Integer.parseInt(args[3]); sessionID = Long.parseLong(args[5]); break; case "inquiry": account = Integer.parseInt(args[3]); sessionID = Long.parseLong(args[4]); break; case "statement": account = Integer.parseInt(args[3]); startDate = new Date(args[4]); endDate = new Date(args[5]); sessionID = Long.parseLong(args[6]); break; }
  • 16. } } 2. Exceptions: ● InsufficientFundsException: package exceptions; public class InsufficientFundsException extends Exception{ public InsufficientFundsException(){ super("Insufficient Funds"); } } ● InvalidAccountException: package exceptions; public class InvalidAccountException extends Exception { public InvalidAccountException(int acnum){ super("Account with account number: " + acnum + " does not exist"); } } ● InvalidArgumentException: package exceptions; public class InvalidArgumentException extends Exception{ public InvalidArgumentException() { super("Invalid command line arguments entered"); } }
  • 17. ● InvalidLoginException: package exceptions; public class InvalidLoginException extends Exception { public InvalidLoginException() { super("Your Login Details are Invalid"); } } ● InvalidSessionException: package exceptions; public class InvalidSessionException extends Exception { public InvalidSessionException() { super("Your session has timed out after 5 minutes of inactivity. Please Log In again"); } } ● StatementException: package exceptions; public class StatementException extends Exception { public StatementException(String msg){ super(msg); } }
  • 18. 3. Interfaces: ● BankInterface: package interfaces; import exceptions.*; import server.Account; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.Date; public interface BankInterface extends Remote { long login(String username, String password) throws RemoteException, InvalidLoginException; double deposit(int accountnum, double amount, long sessionID) throws RemoteException, InvalidSessionException; double withdraw(int accountnum, double amount, long sessionID) throws RemoteException, InvalidSessionException, InsufficientFundsException; Account inquiry(int accountnum, long sessionID) throws RemoteException, InvalidSessionException; StatementInterface getStatement(int accountnum, Date from, Date to, long sessionID) throws RemoteException, InvalidSessionException, StatementException; Account accountDetails(long sessionID) throws RemoteException, InvalidSessionException; } ● StatementInterface: package interfaces; import java.io.Serializable; import java.util.Date; import java.util.List; public interface StatementInterface extends Serializable {
  • 19. public int getAccountnum(); // returns account number associated with this statement public Date getStartDate(); // returns start Dateof StatementInterface public Date getEndDate(); // returns end Dateof StatementInterface public String getAccoutName(); // returns name of account holder public List getTransations(); // returns list of Transaction objects that encapsulate details about each transaction } 4. Server: ● Account: package server; import java.io.Serializable; import java.util.ArrayList; import java.util.List; //Account class, which holds user details, transactions and balance public class Account implements Serializable { //Instance variables for each account object private double balance; private String username, password; private int accountNumber; private List<Transaction> transactions; //static variable to control account numbers private static int nextAcNum = 88769912; public Account (String uName, String pass) { this.transactions = new ArrayList<>();
  • 20. this.username = uName; this.password = pass; this.accountNumber = nextAcNum; this.balance = 0; //increment account number, so next one will be updated nextAcNum++; } //add new transactions to the account public void addTransaction(Transaction t) { this.transactions.add(t); } //getters and setters public String getUserName() { return username; } public void setUserName(String userName) { this.username = userName; } public double getBalance() { return this.balance; } public void setBalance(double balance) { this.balance = balance; } public String getPassword() { return this.password; } public void setPassword(String password) {
  • 21. this.password = password; } public int getAccountNumber() { return this.accountNumber; } public void setAccountNumber(int accountNumber) { this.accountNumber = accountNumber; } public List<Transaction> getTransactions(){ return this.transactions; } @Override public String toString() { return this.accountNumber + " " + this.balance; } } ● Bank: package server; import exceptions.*; import interfaces.*; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Date; import java.util.List;
  • 22. //Bank Class which implements all the methods defined in the BankInterface public class Bank extends UnicastRemoteObject implements BankInterface { private List<Account> accounts; // users accounts private List<Session> sessions, deadSessions; public Bank() throws RemoteException { super(); //set up ArrayLists and create test accounts accounts = new ArrayList<>(); sessions = new ArrayList<>(); deadSessions = new ArrayList<>(); accounts.add(new Account("user1", "pass1")); accounts.add(new Account("user2", "pass2")); accounts.add(new Account("user3", "pass3")); } public static void main(String args[]) throws Exception { try { //Set up securitymanager for server, and specify path to the policy file System.setSecurityManager(new SecurityManager()); System.out.println("n -------------------nSecurity Manager Set"); //Add bank to the RMI registry so it can be located by the client String name = "Bank"; BankInterface bank = new Bank(); Registry registry = LocateRegistry.getRegistry(Integer.parseInt(args[0]));
  • 23. registry.rebind(name, bank); System.out.println("Bank Server Bound"); System.out.println("Server Staredn------------------- n"); } catch (Exception e) { e.printStackTrace(); } } @Override public long login(String username, String password) throws RemoteException, InvalidLoginException { //Loop through the accounts to find the correct one for given username and password for(Account acc : accounts) { if(username.equals(acc.getUserName()) && password.equals(acc.getPassword())){ System.out.println(">> Account " + acc.getAccountNumber() + " logged in"); //Create a new session on Successfull login, and return ID to the client Session s = new Session(acc); sessions.add(s); return s.sessionId; } } //Throw exception if login details are not valid throw new InvalidLoginException(); } @Override public double deposit(int accountnum, double amount, long sessionID) throws RemoteException, InvalidSessionException { //Check if user session is active, based on sessionID passed by client if(checkSessionActive(sessionID)) {
  • 24. Account account; try { //Get the correct account account = getAccount(accountnum); account.setBalance(account.getBalance() + amount); //Create transaction object for this transaction and add to the account Transaction t = new Transaction(account, "Deposit"); t.setAmount(amount); account.addTransaction(t); System.out.println(">> E" + amount + " deposited to account " + accountnum + "n"); //return balance to client return account.getBalance(); } catch (InvalidAccountException e) { e.printStackTrace(); } } return 0; } @Override public double withdraw(int accountnum, double amount, long sessionID) throws RemoteException, InsufficientFundsException, InvalidSessionException { //Check if user session is active, based on sessionID passed by client if(checkSessionActive(sessionID)) { try { //Get correct user account based on accountnum Account account = getAccount(accountnum); //Check if withdrawal can be made, based on account balance
  • 25. if (account.getBalance() > 0 && account.getBalance() - amount >= 0) { account.setBalance(account.getBalance() - amount); //create new Transaction and add to account Transaction t = new Transaction(account, "Withdrawal"); t.setAmount(amount); account.addTransaction(t); System.out.println(">> E" + amount + " withdrawn from account " + accountnum + "n"); //return updated balance return account.getBalance(); } } catch (InvalidAccountException e) { e.printStackTrace(); } } //Throw exception if account doesn't have enough money to withdraw throw new InsufficientFundsException(); } @Override public Account inquiry(int accountnum, long sessionID) throws RemoteException, InvalidSessionException { //Check if session is active based on sessionID that is passed in if(checkSessionActive(sessionID)) { try { //Get account and return to the client Account account = getAccount(accountnum);
  • 26. System.out.println(">> Balance requested for account " + accountnum + "n"); return account; } catch (InvalidAccountException e) { e.printStackTrace(); } } return null; } @Override public Statement getStatement(int accountnum, Date from, Date to, long sessionID) throws RemoteException, InvalidSessionException, StatementException { //Check if the session is active based on sessionID from client if(checkSessionActive(sessionID)) { try { //Get correct user account Account account = getAccount(accountnum); System.out.println(">> Statement requested for account " + accountnum + " between " + from.toString() + " " + to.toString() + "n"); //Create new statement using the account and the dates passed from the client Statement s = new Statement(account, from, to); return s; } catch (InvalidAccountException e) { e.printStackTrace(); } } //throw exception if statement cannot be generated
  • 27. throw new StatementException("Could not generate statement for given account and dates"); } @Override public Account accountDetails(long sessionID) throws InvalidSessionException { //Get account details based on the session ID //Each session has an associated account, so the accounts can be retrieved based on a session //Used on the client for looking up accounts for(Session s:sessions){ if(s.getClientId() == sessionID){ return s.getAccount(); } } //Throw exception if session isn't valid throw new InvalidSessionException(); } private Account getAccount(int acnum) throws InvalidAccountException{ //Loop through the accounts to find one corresponding to account number passed from the client //and return it for(Account acc:accounts){ if(acc.getAccountNumber() == acnum){ return acc; } } //Throw exception if account does not exist throw new InvalidAccountException(acnum); }
  • 28. private boolean checkSessionActive(long sessID) throws InvalidSessionException{ //Loop through the sessions for(Session s : sessions){ //Checks if the sessionID passed from client is in the sessions list and active if(s.getClientId() == sessID && s.isAlive()) { //Prints session details and returns true if session is alive System.out.println(">> Session " + s.getClientId() + " running for " + s.getTimeAlive() + "s"); System.out.println(">> Time Remaining: " + (s.getMaxSessionLength() - s.getTimeAlive()) + "s"); return true; } //If session is in list, but timed out, add it to deadSessions list //This flags timed out sessions for removeAll //They will be removed next time this method is called if(!s.isAlive()) { System.out.println("n>> Cleaning up timed out sessions"); System.out.println(">> SessionID: " + s.getClientId()); deadSessions.add(s); } } System.out.println(); list } // cleanup dead sessions by removing them from sessions sessions.removeAll(deadSessions); //throw exception if sessions passed to client is not valid throw new InvalidSessionException();
  • 29. } ● Session: package server; import java.io.Serializable; import java.util.Date; import java.util.Timer; import java.util.TimerTask; //Session Object //extends TimerTask, a thread that can be called at certaintime intervals //this allows the session to time to be incremented every second, and can be cancelled after 5mins (300s) public class Session extends TimerTask implements Serializable{ //Instance variables for each session object private int timeAlive; private Timer timer; private volatile boolean alive; private Account account; public long sessionId; //static variables to specify max session time, and timer delay private static final int MAX_SESSION_LENGTH = 60 * 5; private static final long DELAY = 1000; public Session(Account account) { //generate a random 6 digit sessionID this.sessionId = (int)(Math.random()*900000)+100000; this.account = account; this.alive = true; this.timeAlive = 0;
  • 30. //create timer object to allow the task to be scheduled to run every second this.timer = new Timer(); this.startTimer(); System.out.println(">> Session " + sessionId + " createdn"); } private void startTimer() { //schedule timer to run every second this.timer.scheduleAtFixedRate(this, new Date(System.currentTimeMillis()), DELAY); } @Override public void run() { //increment the time the session has been alive //updates once every second, so it represents the # of seconds the session has been alive for this.timeAlive++; //if session has been alive for 5 minutes if(this.timeAlive == MAX_SESSION_LENGTH) { //set alive to false and cancel the timer this.alive = false; this.timer.cancel(); System.out.println("n --------------------------nSession " + this.sessionId + " terminated n -------------------------- "); System.out.println(this); System.out.println("-------------------------- "); } } //Getters and Setters public boolean isAlive() { return this.alive;
  • 31. } public long getClientId(){ return this.sessionId; } public int getTimeAlive(){ return this.timeAlive; } public int getMaxSessionLength(){ return MAX_SESSION_LENGTH; } public Account getAccount(){ return this.account; } @Override public String toString() { return "Account: " + this.account.getAccountNumber() + "nSessionID: " + this.sessionId +"nTime Alive: " + this.timeAlive + "nAlive: " + this.alive; } } ● Statement: package server; import interfaces.StatementInterface; import java.io.Serializable; import java.util.ArrayList; import java.util.Date;
  • 32. import java.util.List; import java.util.stream.Collectors; public class Statement implements StatementInterface, Serializable { //Instance variables for each Statement object private List<Transaction> relevantTransactions; private Date startDate, endDate; private Account account; public Statement(Account account, Date start, Date end){ this.relevantTransactions = new ArrayList<>(); this.account = account; this.startDate = start; this.endDate = end; } @Override public int getAccountnum() { return this.account.getAccountNumber(); } @Override public Date getStartDate() { return this.startDate; } @Override public Date getEndDate() { return this.endDate; } @Override public String getAccoutName() { return account.getUserName();
  • 33. } @Override public List getTransations() { //Get all the relevantTransactions for the dates passed in this.account.getTransactions().stream() //filter transactions based on if the date is before the given date or not .filter(transactions -> transactions.getDate().after(this.startDate) && transactions.getDate().before(this.endDate)) //create list from these filtered transactions .collect(Collectors.toList()) //for each transaction in the list, add it to the relevantTransactions list that will be returned .forEach(date -> relevantTransactions.add(date)); return this.relevantTransactions; } } ● Transaction: package server; import java.io.Serializable; import java.text.SimpleDateFormat; import java.text.DecimalFormat; import java.util.Date; //Transaction Class which tracks transaction dates, and other transaction details public class Transaction implements Serializable { //Instance variables private Date date;
  • 34. private String type; private double amount; private Account account; private double accBalance; public Transaction(Account account, String type) { this.account = account; this.accBalance = 0; this.type = type; this.date = new Date(System.currentTimeMillis()); } public Date getDate() { return this.date; } public int getAccountNumber() { return this.account.getAccountNumber(); } public String getType() { return this.type; } public void setType(String type) { this.type = type; } public double getAmount() { return this.amount; } public void setAmount(double amount) { //update transaction amount and get the new account balance, based on withdrawal or deposit
  • 35. double amt = this.account.getBalance(); this.accBalance = this.type.equals("Deposit") ? this.accBalance = amt + this.amount : amt - this.amount; this.amount = amount; } @Override public String toString() { //Print transaction details based on transaction type //Date and Decimals are formatted to print nicely on the screen SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); DecimalFormat df = new DecimalFormat(); df.setMaximumFractionDigits(2); if(this.type.equals("Deposit")) return dateFormat.format(this.date) + "t" + this.type + "ttt" + this.amount + "tt" + df.format(this.accBalance); else return dateFormat.format(this.date) + "t" + this.type + "tt" + this.amount + "tt" + df.format(this.accBalance); } } 8. CONCLUSION: In this project we have used the concept of distributed systems, to create two remote consoles, namely the client side and the server side. We have used the concept of RMI in java, to connect the two consoles. We have invoked operations run on the client side, and used the concept of RMI to complete the invoked operations on the server side. While completing the project, we understood and gained clarity on various concepts like RMI, distributed systems, etc.