Project in Java and C++
In this Project I implemnted an online movie rental service (R.I.P Blockbuster) server and client. The communication between the server and the client(s) will be performed using a text based communication protocol, which will support renting, listing and returning of movies.
The implementation of the server based on the Thread-Per-Client (TPC) and Reactor servers. The servers, do not support bi-directional message passing. Any time the server receives a message from a client it can reply back to that specific client itself, in addition we can send messages between clients, or broadcast an announcment to all clients.
The User Service Text-based protocol is the base protocol which will define the message structure and base command. Since the service requires data to be saved about each user and available movies for rental, I implement JSON text database which will be read when the server starts and updated each time a change is made.
Note that these kinds of services that use passwords and/or money exchange require additional encryption protocols to pass sensitive data. In my implemtion I will ignore security and focus on network programming.
The client is a simple terminal-like in C++. To simplify matters, commands will be written by keyboard and sent “as is” to the server.
Upon connecting, a client must identify themselves to the system. In order to identify, a user must be registered in the system. The LOGIN command is used to identiy. Any command (except for REGISTER) used before the login is complete will be rejected by the system.
A message is defined by a list of characters in UTF-8 encoding following the special character ‘\n’.
In the following section we will entail a list of commands supported by the User Service Text-based protocol. Each of these commands will be sent independently within the encoding defined in the previous section.
Annotations:
- -x- – defines mandatory data to be sent with the command
- " [x] " – defines optional data to be sent with the command
- “ x ” – strings that allow a space or comma in complex commands will be wrapped with quotation mark (more than a single argument)
- x,… - defines a variable list of arguments
The acknowledge command is sent by the server to reply to a successful request by a client. Specific cases are noted in the Client commands section.
The error command is sent by the server to reply to a failed request. Specific cases are noted in the Client commands section.
The broadcast command is sent by the server to all logged in clients. Specific cases are noted in the Client commands section.
Used to register a new user to the system.
- Username – The user name.
- Password – the password.
- Data Block – An optional block of additional information that may be used by the service. In case of failure, an ERROR command will be sent by the server: ERROR registration failed
Reasons for failure:
- The client performing the register call is already logged in.
- The username requested is already registered in the system.
- Missing info (username/password).
- Data block does not fit service requirements (defined in rental service section). In case of successful registration an ACK command will be sent: ACK registration succeeded
Used to login into the system.
- Username – The username.
- Password – The password. In case of failure, an ERROR command will be sent by the server: ERROR login failed
Reasons for failure:
- Client performing LOGIN command already performed successful LOGIN command.
- Username already logged in.
- Username and Password combination does not fit any user in the system. In case of a successful login an ACK command will be sent: ACK login succeeded
Sign out from the server. In case of failure, an ERROR command will be sent by the server: ERROR signout failed
Reasons for failure:
- Client not logged in. In case of successful sign out an ACK command will be sent: ACK signout succeeded After a successful ACK for sign out the client terminate!
A general call to be used by clients. For example, our movie rental service will use it for its applications. The next section will list all the supported requests.
- Name – The name of the service request.
- Parameters,.. – specific parameters for the request. In case of a failure, an ERROR command will be sent by the server: ERROR request -name- failed
Reasons for failure:
- Client not logged in.
- Error forced by service requirements (defined in rental service section). In case of successful request an ACK command will be sent. Specific ACK messages are listed on the service specifications.
- Movie Rental Service
Our server will maintain two datasets with JSON text files. One file will contain the user information and the other the movie information. More about the files and the JSON format in the next section. A new user must register in the system before being able to login. Once registered, a user can use the login command to identify themselves and start interacting with the system using the REQUEST commands.
When a REGISTER command is processed the user created will be a normal user with credit balance 0 by default. The service requires additional information about the user and the data block is where the user inserts that information. In this case, the only information we save on a specific user that is recieved from the REGISTER command is the users origin country.
REGISTER -username-password- country=”-country name-”
The REQUEST command is used for most of the user operations. This is the list of service specific request and their response messages. These commands are available to all logged in users.
Server returns the user’s current balance within an ACK message: "ACK balance -balance-"
Server adds the amount given to the user’s balance. The server will return an ACK message: "ACK balance -new balance- added -amount-"
Server returns information about the movies in the system. If no movie name was given a list of all movies’ names is returned (even if some of them are not available for rental). If the request fails an ERROR message is sent.
Reasons of failure:
- The movie does not exist If the request is successful, the user performing the request will receive an ACK command: "ACK info (”movie name”, … )". If a movie name was given: "ACK info -”movie name”-No. copies left-price-”banned country”,… ".
Server tries to add the movie to the user rented movie list, remove the cost from the user’s balance and reduce the amount available for rent by 1. If the request fails an ERROR message is sent.
Reasons for failure:
- The user does not have enough money in their balance
- The movie does not exist in the system
- There are no more copies of the movie that are available for rental
- The movie is banned in the user’s country
- The user is already renting the movie If the request is successful, the user performing the request will receive an ACK command: "ACK rent -”movie name”- success". The server will also send a broadcast to all logged-in clients: "BROADCAST movie -”movie name” -No. copies left -price-"
Server tries to remove the movie from the user rented movie list and increase the amount of available copies of the movies by 1. If the request fails an ERROR message is sent.
Reasons of failure:
- The user is currently not renting the movie
- The movie does not exist If the request is successful, the user performing the request will receive an ACK command: "ACK return -”movie name”- success". The server will also send a broadcast to all loggedin clients: "BROADCAST movie -”movie name”-No. copies left-price-".
These commands are only eligible to a user marked as admin. They are meant to help a remote super user to manage the list of movies. Any time a normal user attempts to run one of the following commands it will result in an error message.
The server adds a new movie to the system with the given information. The new movie ID will be the highest ID in the system + 1. If the request fails an ERROR message is sent.
Reason to failure:
- User is not an administrator
- Movie name already exists in the system
- Price or Amount are smaller than or equal to 0 (there are no free movies) If the request is successful, the admin performing the request will receive an ACK command:" ACK addmovie -”movie name”- success". The server will also send a broadcast to all logged-in clients: "BROADCAST movie -”movie name”-No. copies left-price-".
Server removes a movie by the given name from the system. If the request fails an ERROR message is sent.
Reason to failure:
- User is not an administrator
- Movie does not exist in the system
- There is (at least one) a copy of the movie that is currently rented by a user If the request is successful, the admin performing the request will receive an ACK command: "ACK remmovie -”movie name”- success". The server will also send a broadcast to all logged-in clients: "BROADCAST movie -”movie name”- removed".
Server changes the price of a movie by the given name. If the request fails an ERROR message is sent.
Reason to failure:
- User is not an administrator
- Movie does not exist in the system
- Price is smaller than or equal to 0 If the request is successful, the admin performing the request will receive an ACK command: "ACK changeprice -”movie name”- success". The server will also send a broadcast to all logged-in clients: "BROADCAST movie -”mov;ie name”-No. copies left-price-".
We will have two JSON files that are in the server-side. One is “Users.json”, which stores information about the customers registered to the online store. The other is “Movies.json”, which stores information about the warehouse, i.e. movies that the online store offers and information about them. Every change in the state of the store must be updated into the files (movie rented, movie returned, movie removed, user registered etc.)
Please see the supplied file example_Users.json The file implies that the store currently contains 3 users:
-
User “john”, an admin, with password “potato”, from the United States, no movies rented and has a $0 balance.
-
User “lisa”, a normal user (customer), with password “chips123”, from Spain, currently has (by rent) the movies “The Pursuit of Happyness” (movie id 2) and “The Notebook” (movie id 3), and has a balance of $37.
-
User “shlomi”, a normal user (customer), with password “cocacola”, from Israel, currently has (by rent) the movies “The Godfather” (movie id 1) and “The Pursuit of Happyness” (movie id 2), and has a balance of $112.
Please see the supplied file example_Movies.json The file implies that the store currently contains 4 movies:
-
The movie “The Godfather”, of price 25, which is banned in both the United Kingdom and Italy. The immediate amount available for rental is 1, and the total number of copies the store owns is 2 (but one of them is currently rented by the user shlomi as seen in the previous Users.json file)
-
The movie “The Pursuit of Happyness”, of price 14, which is not banned in any country. The immediate amount available for rental is 3, and the total number of copies the store owns is 5 (but two of them are currently rented by users shlomi and lisa)
-
The movie “The Notebook”, of price 5, which is not banned in any country. The immediate amount available for rental is zero (none), and the total number of copies the store owns is 1 (it is rented by lisa)
-
The movie “Justice League”, of price 17, which is banned in Jordan, Iran and Lebanon. The immediate amount available for rental is 4, and the total number of copies the store owns is 4 (no one is renting the movie currently) Note: you may assume movie prices and user balance is an integer.
The following section contains examples of commands running on client. It assumes that the software opened a socket properly and a connection has been initiated. I use “<” for screen output at the client side only. Server and client actions are explained in between. Assume that the starting state of the Server is as presented in the example database files shown in section 3. (and it is the case from an example to another example, ie, each example starts from that state)
Further assumptions:
- The current client is not logged in yet.
- The user shlomi is not logged in.
-
REGISTER shlomi tryingagain country="Russia"
- < ERROR registration failed (registration failed because the username shlomi is already taken)
-
REQUEST balance info (server checks if the user is logged in)
- < ERROR request balance failed (it failed because the user is not logged in)
-
LOGIN shlomi mahpass (server checks user-pass combination)
- < ERROR login failed (it failed because the password is wrong)
-
LOGIN shlomi cocacola
- < ACK login succeeded
-
REQUEST balance info
- < ACK balance 112
-
LOGIN shlomi moipass
- < ERROR login failed (this client is already logged in as shlomi)
-
REQUEST info
- < ACK info "The Godfather" "The Pursuit Of Happyness" "The Notebook" "Justice League"
-
REQUEST info "The Notebook"
- < ACK info "The Notebook" 0 5
-
REQUEST rent "The Notebook"
- < ERROR request rent failed (it failed because there are no available copies)
-
REQUEST rent "Justice League"
- < ACK rent "Justice League" success (at this point the file Users.json is updated that shlomi has rented "Justice League", his balance is lowered from 112 to 95 and the file Movies.json is updated that there is one less copy available of Justice League)
- < BROADCAST movie "Justice League" 3 17
-
REQUEST balance info
- < ACK balance 95
-
REQUEST changeprice “The Notebook” 22
- < ERROR request changeprice failed (because shlomi is not an admin)
-
REQUEST return "The Notebook"
- < ERROR request return failed (because shlomi does not own The Notebook)
-
REQUEST info "The Godfather"
- < ACK info "The Godfather" 1 25 "united kingdom" "italy"
-
REQUEST return "The Godfather"
- < ACK return "The Godfather" success
- < BROADCAST movie "The Godfather" 2 25
-
REQUEST balance info
- < ACK balance 95
- < BROADCAST movie “The Godfather” removed (an admin, which is not the current user, removed The Godfather from the available movies)
-
SIGNOUT
- < ACK signout succeeded (client’s app closes at this stage)
Further assumptions:
- The current client is not logged in yet.
-
REGISTER steve mypass country="iran"
- < ACK registration succeeded (remember to update Users.json)
-
REQUEST balance info
- < ERROR request balance failed (it failed because the user has not logged in yet)
-
LOGIN steve mypass
- < ACK login succeeded
-
REQUEST balance info
- < ACK balance 0
-
REQUEST balance add 50
- < ACK balance 50 added 50
- < BROADCAST movie "The Godfather" 2 25 (some user, which is not the current user, rented or returned The Godfather)
-
REQUEST rent "Justice League"
- < ERROR request rent failed (because Steve is from Iran and Justice League is banned there)
-
SIGNOUT
- < ACK signout succeeded (client’s app closes at this stage)
- The client is not logged in yet
- The admin (user john) is not logged in
-
LOGIN john potato
- < ACK login succeeded
-
REQUEST remmovie “The Godfather"
- < ERROR request remmovie failed (because The Godfather has a copy rented by shlomi)
-
REQUEST remmovie "Justice League"
- < ACK remmovie "Justice League" success (succeeds because no one has rented this movie yet)
- < BROADCAST movie "Justice League" removed (remember that even the admin is a user, that’s why he received a broadcast as well)
-
REQUEST addmovie “South Park: Bigger, Longer & Uncut” 30 9 “Israel” “Iran” “Italy”
- < ACK addmovie “South Park: Bigger, Longer & Uncut” success
- < BROADCAST movie " South Park: Bigger, Longer & Uncut" 30 9
-
SIGNOUT
- < ACK signout succeeded (client’s app closes at this stage)