Bank Project

Authors:

Greg DeAngelis and Jason Moiron

Table of Contents

Overview

The object of the assignment was to create a distributed banking system using web-services to create a client-facing API and a simple GUI that uses the API to perform banking operations on accounts. The webservices stack used was Axis2, and the supported banking operations are:

features

All of the "A" features are implemented, including distributed querying amongst servers and failovers. See the bootstrapping section on how to set up the system.

Architecture

We split the project up into 3 logical pieces:

These pieces correspond to the "customer facing application" and the two tiers of our architecture. A request passing through the system from one GUI to it's BranchServer looks like this:

architecture_overview

BranchGUI

The BranchGUI is a simple java program with a Swing GUI that allows a client to interact with a single branch of the bank via a webservice frontend. For simplicity, it uses the synchronous RPC method of communicating with the Axis2 webservice stack.

Before the GUI can be used to perform bank actions, the WebService parameters (the IP and Port that Axis2 is running on) must be entered in the connect dialog. After this, the user can then issue the 4 actions mentioned in the assignment spec as well as a listAccounts method that lists all accounts and their ballances on the branch that the client is connected to. This was done for debug purposes, but was kept in the final product to ease the verification of the correctness of backup servers and Branch -> Branch transfers.

BranchService

The BranchService is an Axis2 deployable webservice that provides the WSDL and SOAP API for the BranchGUI.

After attempting to put most of the functionality of a bank Branch into the BranchService, we decided that coupling functionality with the webservice stack gave us an environment that was too constrained. We decided to abandon a 1-Tier method in favor of a 2 Tier method where the BranchService is providing an interface on the one side to the BranchGUI, but issuing transaction requests to a remote BranchServer that contains the actual Branch state. This has a number of advantages:

Getting parameters through Axis2 to our code was extremely difficult. We wanted to have a systme that could more or less bootstrap itself with only input that could be provided reasonably on the command line. In order to stress the independence of each bank Branch, the decision was made to require each Branch to have it's own stack of Axis2. We also did not want to be running n slightly different versions of the Branch software to have a system of n branches. By running the actual Branch state in a second tier, we were able to bootstrap much easier.

The branches must already communicate amongst themselves, forwarding client requests to foreign branches when they don't house the requested account. Because this protocol was already required, it was easy to just let the BranchService piece communicate with it's Branch in the same way that the Branches communicate with eachother.

Finally, the Branches do not recognize a difference between a local request (one made by their own corresponding BranchGUI) and a foreign one. This is because the BranchService issues requests to the actual Branch state in the same manner as other Branches do. Although this complicates the design slightly it also simplifies the distributed aspect, as once one server was up and running we could rely both on our WebService interface and our backend Branch -> Branch interface.

BranchServer

The BranchSever is the program that keeps the state of a Branch. It fields requests from it's BranchService and form other BranchServers. This is all done over one listener port, so the BranchServer doesn't actually need to know (or care) whether or not the request is coming from it's own BranchService or from other BranchServers. A system running 3 branches is illustrated below:

3 Branches

All of the arrows going into the BranchServers represent connections using the backend TCP based protocol on the same port. In the event of a failure, a BranchServer that had been running under "backup mode" would take over that port (if it was available). This creates a restriction on a a backup server that would be undesirable in real life: that it must run on the same computer as the primary.

Building

The provided ant build script build.xml has a few targets to build the various components. These are:

It is important to set the path to the axis2 libraries. In order to do this, run ant with the -D option and supply the axis2.home variable. You can also set the "axis2.home" variable inside the build script. If you have unzipped axis in ~/webservices/axis2-1.2, then you can build the targets like this:

ant -Daxis2.home ~/webservices/axis2-1.2 [service|client|server]

Running

Running the system in the right order and with the right parameters is unfortunately not entirely straight forward.

Bootstrapping

As mentioned before, we had difficulty supplying parameters to our BranchService processes. Since we wanted to run one copy of Axis2 per BranchService, and we did not want those copies to differ, we had to feed the service parameters in some other way. The ammount of information that each Branch process needed to know, along with the time constraints of doing the project, forced us into using a fairly inelegant solution: The entire system state must be described in a number of property files.

properties

The proper sequence in which to do things is:

ant -Daxis2.home <dir> -Daxis2.port <dir> prepare-axis2
ant -Daxis2.home <dir> server
ant -Daxis2.home <dir> client
ant -Daxis2.home <dir> run-axis2
java -jar dist/BranchServer <properties_file>
java -jar dist/BranchServer -b <properties_file>

Running the BranchClient

Running the BranchClient is straightforward. You may use the ant script, or run the client with java -jar BranchClient.jar. The MANIFEST inside the jar file sets the class path the same as when you built it, so if it builds it should also run.

Running the BranchService

The build target for the BranchService is going to place a BranchService.aar file in your build directory as well as in {$axis2.home}/repository/services. If your Axis2 setup requires the aar file to be elsewhere, you'll have to configure that on your own.

The easiest way to run the BranchService is to run it through ant via the build.xml build script. There are 2 special Axis2 build targets provided:

The prepare-axis2 build target allows you to craft the 'axis2' directory into a proper SimpleAxis2Server repository as well as the axis2/axis2.xml.template into a proper SimpleAxis2Server conf target. Although setting -Daxis2.home <dir> is not required, setting -Daxis2.port <port> is recommended. This does a simple token replace on the template file to make the Axis2 server run on the designated port. Because of the way that the system is bootstrapped, it is convenient to be able to run many Axis2 servers on the same machine without having to manually edit the configuration file to change ports.

After you have run the prepare-axis2 target, you can use the run-axis2 target to actually run Axis2. It will take care of building the BranchService and placing an updated version of the BranchService.aar file into the axis2 repository for you, and will then run the SimpleAxis2Server. The -Daxis2.home <dir> variable must be set properly for ant/java to find the server.

For more detail on running the service properly and making the system work, see the bootstrapping section.

Running the BranchServer

primary

Running the BranchServer is pretty straightforward. You can use java -jar BranchServer.jar <properties_file>. After the primary starts, you can kill it manually by typing 'quit' in the console.

backup

Running the BranchServer as a backup is pretty much the same as running the primary, except you pass the -b switch. It is important that you start the backup after the primary has been started.