The Chatter Web Project was developed in the Cloud Computing course at Boise State University. It was deployed on three separate Ubuntu 14.04 virtual machines, with one database virtual server, and a load balancer server. The load balancer used HAProxy to keep sticky sessions between the load balanced servers. The project was deployed on Tomcat 8 with a Jersey servlet and a JAX-RS RESTful API. The back end used Hibernate with a MySQL database. The front end implemented PureCSS and JQuery.
The project was broken up into three separate services: friend service, tweet service, and monitor service. The friend service, and tweet service were additionally load balanced using a queuing system to respond to requests.
The monitor service keeps stats on all different types of information about Chatter services running. It displayed them for each individual load balanced servers in a dashboard. The dashboard used the Chart.js library to chart statistics in a responsive manner.
-
pom.xml
- Various build dependencies and plugins used to build Chatter -
ChatterDB2.sql
- Database table builds -
com.andrewcode.queue
-
Controllers
MonitorService.java
The monitor service that returns the rest valuesTaskQueue.java
The worker tasks queue
-
Models
Worker.java
The worker that finishes all the work items
-
Utils
ProcessingFactory.java
The factory that processes the work itemsServletContextListener.java
The listener that sets up the queueResolutionException.java
When you pass in a wrong value for the qps resolution this is thrownWorkItem.java
Worker item interface for work items
-
WorkItems
CreateFriendship.java
Implemented work itemGetIncomingFriends.java
Implemented work itemLogout.java
Implemented work itemCreateUser.java
Implemented work itemGetOutgoingFriends.java
Implemented work itemPostTweet.java
Implemented work itemDestroyFriendship.java
Implemented work itemGetTweet.java
Implemented work itemRetweetTweet.java
Implemented work itemDestroyTweet.java
Implemented work itemGetTweetList.java
Implemented work itemUsernameLogin.java
Implemented work itemGetFollowers.java
Implemented work itemGetUsername.java
Implemented work itemGetFollowing.java
Implemented work itemIdLogin.java
Implemented work item
-
-
com.andrewcode.rest
- Controllers
FriendService.Java
Handles all of the friendships and followers rest callsTweetService.java
Handles all of the tweet related rest callsUserService.java
Handles the creation and login of users
- Models
Friends.java
Hibernate annotated model of table in MySql databaseTweet.java
Hibernate annotated model of table in MySql databaseUser.java
Hibernate annotated model of table in MySql databaseQuery.java
Hibernate annotated model of table in MySql databaseError.java
Hibernate annotated model of table in MySql database
- Util
FriendException.java
Exception handling forFriendService.java
TweetException.java
Exception handling forTweetService.java
UserException.java
Exception handing forUserService.java
- Utils.java Static helper methods that I did not want to copy over and over again
- Controllers
-
Resources
hibernate.cfg.xml
Hibernate connector for hibernate orm library
-
Webapp
- css
jquery.modal.css
CSS files for modals I am using in Viewspure-min.css CSS
framework used in all views of Chatter
- img
close.png
Close icon used for modalsspinner.gif
Spinner gif used for modalsBridge.png
Home page photograph
- js
jquery.modal.min.js
Modal javascript code used for modals in Chatterjquery-2.1.1.min.js
jQuery used for many post and get callsChart.js Javascript
library for charts used in the dashboard
- WEB-INF
web.xml
Configuration file for Chatter
about.html
About me pagefriends.html
FriendService testing page includes all posts and get testsindex.html
UserService testing page includes login, create and find users teststweet.html
TweetService testing page includes all tweet method testsdashboard.html
Testing page for the newly added monitormonitor.html
Front facing page to get you to each individual node's dashboard
- css
CS597-Andrew-Balancer
andrew@132.178.129.1
CS597-Andrew-Database
andrew@132.178.129.2
CS597-Andrew-One
andrew@132.178.128.219
CS597-Andrew-Two
andrew@132.178.129.250
CS597-Andrew-Three
andrew@132.178.129.229
- Create a user in mysql with username = root and password = pass
- Create a database called chatterDB (mysqladmin -uroot -ppass create chatterDB)
- Create all the tables for chatterDB (mysql -uroot -ppass chatterDB < ChatterDB2.sql)
Must then create a username = andrew and password = pass with access to database from the child node ip's.
i.e. The users "Andrew" have access from the host
andrew | 132.178.128.219 |
andrew | 132.178.129.229 |
andrew | 132.178.129.250 |
- Run 'mvn clean package'
- Change directories to 'target/'
- Project was built as 'ROOT.war' (Why ROOT.war? It enables me to deploy Chatter to local host root and not as localhost:8080/Chatter/ Please keep this the same because all jQuery calls are assuming this naming convention.)
- Copy 'ROOT.war' to tomcat deployment directory or deploy using the tomcat manager of each child node
- Deploy the haproxy.cfg and start ha proxy up
- Browse to root (http://CS597-Andrew-Balancer) and Chatter with the monitor should load (Should see a big picture of a bridge)
The existing chatter project will look very similar, but the design of the servers and scaling is very different. The monitor was not very trivial to set up. The first thing I had to do was set up a global database that the three different nodes could connect to. Implementing the load balancer was easy once I figured out how to tell HA Proxy to create a "SEVERID" cookie on the client. This will keep the session the same when accessing the load balancing server. All of this engineering should be completely invisible to the user because of the sticky sessions.
The monitor server is started with the 'queue/' prefix to the url to designate the difference from the rest calls. They accept a 'GET' request with @PathParam annotations. All methods return JSON on success and a WebApplicationException with an error message on an error.
All rest calls have 'rest/' appended to the url to designate rest calls from other web pages in Chatter. All 'POST' calls use the @FormParam and all 'GET' calls use the @PathParam annotations. The project is broken up into three simple services UserService, FriendService, and TweetService. All methods return JSON on success and a WebApplicationException with an error message on an error.
-
MonitorService.java
GET
monitor/processingtime
- Returns an array of average response times in a 10 percentile rangeGET
monitor/queuedepth
- Returns the number of elements in the worker task queueGET
monitor/qps/{resolution}
- Accepts "minutes", "hours", "days", or "months" only. Returns the count of messages past 100 from now. I.e. user types "minutes" and get the count of messages 100 minutes from now.GET
monitor/errors/{type}
- Accepts a valid HTTP error code, only 400 will return a non-zero. Will return a count of the valid error codes passed in.
-
UserService.java
POST
users/create/{user-name}
- Create a user from specific user nameGET
users/{users-name}
- Get a userId from a user namePOST
users/login/{userId}
- Login passes a userId to set for the session
-
FriendService.Java
GET
friendships/incoming
- Returns the users incoming friendship requestsGET
friendships/outgoing
- Returns the users outgoing friendship requestsPOST
friendships/create
- Create a friendship requests if you'd like to accept a friendship request, send a create to that user idPOST
friendships/destroy
- Destroys a friendship completely. Assumed this was a 'unfriend' or 'block' and not just an unfollowGET
friends/list
- Returns a list of userIds of people who the logged in user is followingGET
followers/list
- Returns a list of userIds of people who are following the logged in user
-
TweetService.java
POST
tweet/tweet/{msg}
- Create a tweet that is less that 128 character from passed in messageGET
tweet/show/{id}
- Get a tweet from a specific idPOST
tweet/destroy/{id}
- Delete a tweet from a specific idPOST
tweet/retweet/{id}
- Retweet takes the tweet message, posts it again with a new tweetId and assigns the userId to the user who created the retweet.
-
Additional Rest End Points:
POST
users/login/{user-name}
- Login passes a user-name instead of a userId because it is easier for a user to remember a user name then a idGET
tweet/getTweets
- Returns a list of tweet objects for a users feed (i.e. the tweets from the user or tweets from the people the user is following)POST
users/logout
- Invalidates the users session (Really handy for testing multiple relationships between multiple users)
This project was much more challenging then the previous project. I learned a lot about cookies, sessions,and load balancing with the addition of the HAProxy load balancer. I also continued my knowledge of javascript by creating a dash board for the individual servers. I learned a lot about different design patterns and why the one we chose was the best for us. The individual worker task queue is fast, and it leaves less refactoring for us with our existing service. I still need to learn how to secure the server more (XSS, SQL injection) to name a few. Also I will need to learn more AJAX because the dashboard is a bit primitive without AJAX.
- http://blog.haproxy.com/2012/03/29/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/
- https://serversforhackers.com/editions/2014/07/15/haproxy/
- http://www.chartjs.org/
- http://purecss.io/
- http://www.rackspace.com/knowledge_center/article/mysql-connect-to-your-database-remotely