Project Report
Project Report
1. Introduction
The project “Airline Management System” comprises of a large number of flights which belong
to a particular airline. The system we have implemented manages different objects viz.
Airline
Airline Employees
Customers/Traveller
Each of these accesses a database schema which has corresponding tables. Web services are
used for middleware technology.
2. Individual Contributions
Name Contribution
1
● Employee module: Create Employee, Delete employee, Update
employee info, List/Display employee info, Search employees
● Project report preparation
● Test Harness
● Code Integration
3. Project Requirements
Tier 1 – Client Requirements
Airline management system client has all the functionalities listed as a part of
requirements.
A simple UI is used and appropriate error messages are displayed to the users wherever
necessary. Some of us in the team have used a front end framework called Bootstrap
which contains customizable style sheets and is a faster way to do client side coding.
Tier 2 - Middleware
We have clearly defined interfaces implementing all the required functionalities.
JDBC connection is established for select/insert/update data to database.
JMS is used for publishing the status of flights to all the users who are online.
2
· Cancel an existing reservation
· Issue a flight ticket
· Payment options
· List all customers known by the system
· List all employees known by the system
· List all reservation known by the system
· List all flights known by the system
· Change a employee/ customer information (name, address, etc) ability to change ALL
attributes
· Change a flights information (time, source, destination etc) change ALL attributes
· Search for a employee based on attributes.
· Search for a flight based on attributes
· Display information about a employee
· Display information about a traveler
· Display information about a flight
6. Testing
Test Harness
We have used Soap UI to test the performance of web services. When a new project is created,
we give our wsdl and then add test steps for a specific method. We run the test against certain
number of count.
The below screenshots show the test harness results for payment and update flight status,
3
7. Object management policy
1. Object caching is done for Searching for flights. This helps faster access as searching
flights is one of the most frequently used functionalilities in an airline management
system.
4
-We have used lazy loading for caching. On the first request for a flight search, the
results are cached in a map with source and destination as key. The search results are
mapped to bean files and are stored against the key.
-On the same request, the results are rendered from the cache thus saving database
hits.
-When a flight is updated, the map is looked upon and the object in the map is updated
accordingly.
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import fdpackage.FlightDetailsBean;
if(flightList.get(i).getFlightId()==updatedBean.getFlightId()) {
if(newKey.equals(oldKey)) {
flightList.add(i, updatedBean);
} else {
flightList.remove(i);
}
}
}
journeyToFlightsMap.put(oldKey,
(FlightDetailsBean[])flightList.toArray());
5
}
if(!oldKey.equals(newKey)) {
if(journeyToFlightsMap.containsKey(newKey) &&
journeyToFlightsMap.get(newKey)!=null) {
List<FlightDetailsBean> flightList =
Arrays.asList(journeyToFlightsMap.get(newKey));
flightList.add(updatedBean);
journeyToFlightsMap.put(newKey,
(FlightDetailsBean[])flightList.toArray());
}
}
}
6
2. Java beans: We have used Java Bean classes to handle the functionality and the data
entered. Beans have getter and setter methods for easy management.
package helperClasses;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
7
public static Connection getConnection() throws Exception {
Connection conn = null;
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
/*conn =
ConnectionPool.getConnection("jdbc:mysql://localhost:3306/airline","root","root");*/
conn =
ConnectionPool.getConnection("jdbc:mysql://localhost:3306/airline","root","root");
} catch(Exception e) {
System.out.println("Exception in connecting to DB : ");
e.printStackTrace();
throw e;
}
return conn;
}
package helperClasses;
8
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
SQLException
{
if(connectionList.isEmpty())
{
if(CURRENT_POOL_SIZE>=MAX_POOL_SIZE)
{
throw new MaxPoolReachedException("Maximum pool size
reached cannot create connections");
}
CURRENT_POOL_SIZE++;
System.out.println("creating new connection");
return DriverManager.getConnection(url, username,password);
}
else
{
CURRENT_POOL_SIZE--;
System.out.println("returning from existing connection pool");
return connectionList.get(0);
}
}
9
}
package helperClasses;
9. Policy used for deciding when to write data into the database
Data entered from the UI which
-Doesn’t change often
-Need to available for retrieval
are written into the database.
For instance, customer information once entered may not be changed frequently although
small changes like updating email ID, Address etc can be done. So, such information will be
stored in the database as caching not frequently changing data is not good from performance
perspective.
Example: Details of a Person which can be Employee and Traveller data are written to the
database as it is composed of common data across Traveller and Exmployee and need to be
retrieved upon querying for details related to both.
Object caching is implemented for searching flight information. This saves database hits for
frequently accessed data.
So, as per our policy, we have used lazy loading for caching. On the first request for a flight
search, the results are cached in a map with source and destination as key. The search results
are mapped to bean files and are stored against the key.When a flight is updated, the map is
looked upon and the object in the map is updated accordingly.
10
10. Screen Capture of Client Applications
Login Page
Sign Up
11
Update Customer
Search Flight
12
List Flight
13
Update Flight
14
15
Credit Card 1
Credit Card 2
16
Purchase 1
Purchase 2
17
e Ticket
Ticket
18
Admin Welcome Page – Employee.jsp
19
Create Employee 1
Create Employee 2
20
Create Employee 3
List Employee
21
Search Employee
Search Employee 2
22
Search Result
Update/Delete option
23
Update 1
Update 2
Update 3
24
Delete Employee
Manage Reservations
25
Traveller
Traveller Validation
26
Database creation Scripts
27
passWrd varchar(45) NOT NULL,
email varchar(45) NOT NULL,
PRIMARY KEY(person_id)
);
28
CREATE TABLE IF NOT EXISTS `reservations` (
`reservation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` int(10) NOT NULL,
`no_of_people` int(10) unsigned NOT NULL,
`type_of_journey` varchar(45) NOT NULL,
`status` varchar(32) NOT NULL DEFAULT 'InCheckout',
`creation_date` timestamp NOT NULL DEFAULT '2013-11-20 00:00:00',
`created_by` varchar(45) NOT NULL,
`last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
`last_updated_by` varchar(45) NOT NULL,
PRIMARY KEY (`reservation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
29
Depart_date DATE,
Flight_Source varchar(50),
Flight_Destination varchar(50),
Flight_Depart_Time varchar(8),
Flight_Arr_Time varchar(8),
Flight_fare varchar(10),
No_Of_Seats integer,
Crew_count int(11),
PRIMARY KEY(Flight_Id));
PERSON table
mysql> desc Person
30
EMPLOYEE Table
mysql> desc Employee
FLIGHTDETAILS table
mysql> desc flightDetails;
31
PAYMENT table
mysql> desc Payment;
RESERVATIONS table
mysql> desc Reservations;
RESERVATION_DETAILS table
mysql> desc Reservation_Details;
32
TRAVELLER table
mysql> desc Traveller;
33
Note: Please refer to “Object management policy” section in Page 5
3. To increase reliability
-We have server side validations like null checks
-Proper error handling and displaying appropriate error messages
-The database has tables with referential integrity maintained with the help of an int
field i.e. person_id. This prevents incorrect entry into tables.
4. Scalability
Current implementation has a maximum of 20 database connection objects. If we need
more connections in case more functionalities have to be implemented which need
database access, it can be easily scaled by just changing the number of active
connections in the code.
The Person and Employee tables have 5000 records which re handled by the code.
6. Validations
Basic client side validations include incorrect datatype check, mandatory/non-mandatory
fields handling, pattern matching for specific fields like zip code which is of pattern [0-9][0-
9][0-9][0-9][0-9], Employee ID which is of the pattern of US Social security number etc
Correct navigation from one page to the other is verified.
Module wise testing and end to end integration testing is done
7. JMS
JMS is used for publishing flight status to all the clients. The code listing of the client and Server
is listed below,
//Client code
import java.util.Properties;
import java.util.Scanner;
import java.util.regex.Pattern;
import javax.jms.Connection;
34
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public Client()
{
try
{
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "localhost");
35
connection.start();
}
catch(NamingException NE)
{
System.out.println("Naming Exception: "+NE);
}
catch(JMSException JMSE)
{
System.out.println("JMS Exception: "+JMSE);
}
}
//Server code
import java.util.Properties;
36
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
}
catch(JMSException JMSE)
{
System.out.println("JMS Exception: "+JMSE);
}
}
37
public static void main(String args[])
{
new Server();
}
@Override
public void onMessage(Message message) {
TextMessage TM = (TextMessage)message;
String reply = null;
String[] input = null;
try
{
if( TM.getText().startsWith("Status"))
{
System.out.println("inside server");
input = TM.getText().split(",");
reply=status.getInfo(Integer.parseInt(input[1]));
System.out.println("reply in server "+reply);
sendReply(message, reply);
}
}
catch(JMSException JMSE)
{
System.out.println("JMS Exception: "+JMSE);
}
public Server()
{
try
{
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "localhost");
38
ConnectionFactory conFactory =
(ConnectionFactory)jndi.lookup("XAConnectionFactory");
connection = conFactory.createConnection();
session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE
);
StatusQueue = (Queue)jndi.lookup("queue/StatusQueue");
if(null==StatusQueue)
{
StatusQueue = session.createQueue("StatusQueue");
jndi.bind("StatusQueue", StatusQueue);
}
consumer=session.createConsumer(StatusQueue);
consumer.setMessageListener(this);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
39
public static void main(String[] args) {
// TODO Auto-generated method stub
FlightStatus fs=new FlightStatus();
System.out.println(fs.getInfo(1));
}
catch (SQLException e)
{
e.printStackTrace();
}
return info;
}
40
{
con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/marketplace", "root","install");
}
catch (SQLException e)
{
e.printStackTrace();
}
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return con;
}
Performance measurement
Without Caching
With Caching
41
Observations and lessons learned
1. It is important to finalize the database design well in advance. Though we managed to
discuss the design, we ended up making changes in the way of adding or deleting fields
and figuring out referential integrity issues which consumed quite a lot of time.
2. Integrating modules is another area where being in sync with all the team members is
very important. This was a major learning in terms of working together as a team to avoid
major issues when modules are integrated.
3. Testing along side implementing the code is a good learning in order to spend less time on
fixing issues at the end. This saved a lot of time as each of us tested our modules
individually as well as end-to-end testing was done upon integration to verify major
functionalities.
4. Version control is important for code management. We used emails to forward our code
to each other. Using some version control tool would have been a much easier way to
handle this. It is a learning to be implemented in the next or upcoming projects and
semesters.
42