Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

Resit - Full Stack

Contents

2      Problem statement 2

3       Setting up the database 3

4       Templates 3

5      Methods description 4

5.1    Credentials.java 4

5.2    ResitServer.java 4

5.3    ResitService.java 4

5.4   ResitClient.java 5

6      What to submit? 7

7       Sample outputs 8

7.1    Server output 8

7.2    Client output 8

1 About the resit

IMPORTANT: The resit has 2 parts to be completed in this order:

1.  This programming exercise for which you have 5 days to com- plete, with no time limit other than the deadline indicated below, and no limits on the number of attempts, but only the last sub- mission will be considered. You can do this off-line.

2. A quizz for which you have 40 minutes to complete.  The deadline for submission is the one indicated below. This quizz is time con- strained (max time 40mins i.e. the latest you should start is 15:20) and can only be attempted once. You do this online in canvas.

. Deadline: Friday 25th-Aug-2023 at 16:00 (UK time).

. Late submissions policy: No late submissions allowed.

. What to submit for this part of the resit:  A single  .zip file as explained in Section 6

. Learning outcome: Integrate a database, server, and front-end into a full software stack.

. Where has the skill been learned in the module:

Weeks 1-2 covered front end interface creation using JavaFX.

Week 3 slides for concepts and code on Threads’ creation, execution and termination.

Week 4 slides for concepts and code on Client-Server Architecture.

Weeks 7-8 covered SQL querying.

Weeks 9 slides for concepts and code on JDBC.

2 Problem statement

In this resit, you will be developing a 3-tier TCP-based networking multi- threaded client-server application to consult a database that implements a variation over the game Cluedo; note that there is substantial variation with the real game and you are not  required to implement the original game. In the original game, you play an investigator solving a murder and you must discover the suspect, the weapon and the place by making queries to other players. Here, you play alone and you try to guess some information about the fictitious murder by asking the server.

The application features a client  that offers a JavaFX based graphical user interface to request the service and communicate with a intermediate server providing a query specific service.  The server, located in the local host, will be composed of two parts or classes; one being the main  server which attend request as they arrive on an infinite loop, and the  server’s service provider  that are created to attend each service.  It is the server’s service provider which does connects to the database using JDBC, retrieves the outcome of the query and sends back the outcome to the client.

Although each service provider thread will only attend 1 request and then stop, the server will attend any number of request by creating new service threads.

The service provided is a fixed but parametrizable query; Given a weapon, a place and a time, the query retrives the list of ages of potential suspects.

Both, the client and the server applications should be able to work withut errors when the query returns no entries. The server will be robust to SQL injection.

In all classes, you are requested to treat exceptions in the method that first can raise themi.e. do not rely in throws clauses to deal with exceptions at a later stage.  If some exceptions requires you to stop the execution of either the servers, or the client without a correct resolution of the request, make sure that in those cases you exit the program with code 1. Exit with code 0 if program execution is correct.

Feel free to use any IDE of your choice, but tests will be carried from the command line. The back end will be implemented in postgreSQL using postgresql-42.6.0.jar driver and should run in a Windows 11 machine.

3 Setting up the database

For this resit you will use the FSAD2023\_Resit database.  This is provided to you.  Download the file resit.sql from Canvas.  Open a postgres shell window and connect with your own credentials.  First, you need to state the path on your own computer where you have the file.  Then import this file is as follows.

\i  resit.sql

Once you have imported the tables, you can list them by performing the following command in PostgreSQL:

\dt

Note that this will list all of the tables you may have created in this database.

Run SQL commands to view the contents of each table by doing

SELECT  *  FROM  tablename;

replacing tablename with the name of the table you want to look at.

4 Templates

You are provided with templates for  all classes in canvas.   The  exercise requires you to fill the gaps clearly identified with;

//TO   BE   COMPLETED

or similar annotations, e.g.

The templates already contain all the atributes, methods, and correct signatures.  There is no need to create more attributes for the classes, nor additional methods,  nor to import new classes or libraries,  but you can declare local variables within the methods as you may need.  Do not alter the signature of the methods.

5 Methods description

Only move to this stage when you have set up the database, as above.

5.1 Credentials.java

The Credentials.java contains the credentials for the database (username, password, url) and for the server connection (host address, port number). You must replace the credentials with your own.  Submitting this class is optional, as we are going to use our own credentials for testing your code. Therefore, you can delete this class from your  .zip file before submitting your resit.

5.2 ResitServer.java

The server main class.  This server provides a service to access the database. The server  application will run indefinitively until  Ctrl+C  (Windows or Linux) or Opt-Cmd-Shift-Esc (Mac OSX) is pressed.  Add your student id in the file opening comments.

. public ResitServer():  Class constructor.   Creates the server socket. Reads the connection credentials from class Credentials.

. public void executeServiceLoop():  Runs the service (infinite) loop. This method accepts the server’s service requests.  The method listens for incoming client requests and creates a service threads to attend the requests as needed.

. public static void main(String[] args):  Provided.   No  need to do anything. Execution.

5.3 ResitService.java

This class is the service provider or client handler.  This class is the one responsible for reading the client request, connect to the database, make the query, retrieve the outcome of the query and sends it back to the client. This class extends Thread.

. public ResitService(Socket aSocket):  Class constructor.  Initializes the server service’s socket attribute and launches the service thread.

. public  String[] retrieveRequest():  Receives the  information corre- sponding to the client request. This method accepts the server’s service requests.  Upon receiving the service request, it parses the message to remove the termination character (‘#’) from the incoming message.  The message will arrive in the form of a string.  The remaining part of the incoming message contains the three parameters of the query; that is, the weapon, the place and the time of the murder separated by a semicolon; e.g.  ‘gun;Kitchen;10:00’.  This method must parse the message splitting this message content into its components and return a String[] with three elements;  the  first  one being the weapon,  the second being the place and the third being the time in format ‘HH:mm’ .

. public boolean attendRequest():  This method provides the actual service.  It connects to the database, make the query, execute the query and retrieve the outcome and process the query.   It  should be robust to SQL injection.  The connection, statement and result set should be closed properly afterwards.   The  processing  of the query will transfer the contents of the ResultSet obtained from executing the query, into a CachedRowSet object that can survive the closing of the connection and can be sent over a socket (i.e.  it requires to be serializable).  The method returns a flag indicating whether the service has been attended sucessfully.   Finally,  to transfer the  contents of the ResultSet into a CachedRowSet object you can use;

RowSetFactory   aFactory  =   RowSetProvider. newFactory(); CachedRowSet   crs  =   aFactory. createCachedRowSet();

crs. populate(rs);  //with  rs  being   the   ResultSet

variable .

. public void returnServiceOutcome(): Communicate the service out- come back to the client.  This method returns the outcome of the request to the client and closes the service’s socket. To send full objects through a socket you can use ObjectOutputStream. For instance;

ObjectOutputStream   outcomeStreamWriter  =  new

ObjectOutputStream (...);

outcomeStreamWriter. writeObject (...);

. public void run (): Provided. No need to do anything. Execution.

5.4 ResitClient.java

This is the client or service consumer.  It is a JavaFX application with a simple GUI (See Figure 1) with 2 major parts;

. An input area with three TextFields to insert the query parameters and a button to request the service every time it is pushed.

. An output area with a TableView to render the outcome of the last query.

Note that the same client can request the service many times by simply pressing the button again, and in every request, the current selected values

in the input boxes will be used for parameterizing the query.  Note that you do not transmit the query, but only the values of the parameters.

In order to adequately populate the TableView with the result, the class also has an internal nested class MyTableRecord (Provided. No need to do anything.).

. public ResitClient():  Provided.  No need to do anything.  Class con- structor.   Initializes  the  attribute  storing  the  application  instance  in javafx.

. public void initializeSocket():  Initializes the client socket using the credentials in class Credentials.

. public void requestService():  This methods requests the service.  It adds a terminating character (‘#’) to the service request message and sends the message to the server via the client socket.

. public void reportServiceOutcome():  Receives the outcome of the service and renders such outcome in the output area of the interface. The service outcome is received by deserializing the CachedRowSet object using ObjectInputStream; e.g.

Object InputStream   outcomeStreamReader   =  new

Object InputStream(outcomeStream);

serviceOutcome   =   (CachedRowSet)

outcomeStreamReader. readObject();

Upon receiving this outcome, the method iterates over outcome to update the table contents.  For this, you will use the aforementioned nested class MyTableRecord, e.g.

ObservableList  tmpRecords   =

result. get Items();

//Here ,  result   is   the   TableView   object .

tmpRecords. clear();  //Clear  the   table   content

while   (this . serviceOutcome. next())  {

...

}

result. set Items(tmpRecords);  //Update  table   contents

. public void execute():  This method implements the callback action to be execute when the button to request the service is pushed.  In or- der to do so, it has to create a service request message containing the parameters of the query by reading the values at the input TextFields; that is, the weapon, the place and the time separated by a semicolon; e.g. ‘gun;Kitchen;10:00’, and save this into the userCommand attribute.  This method will then further proceed to initialize the socket, request the ser- vice and report the service outcomeby calling the appropriate methods. Finally, it closes the connection with the server’s socket.

. public void start(Stage primaryStage):  Provided.  No need to do anything. This is JavaFX’s main method.  This method creates the GUI.

. public static void main  (String[] args):  Provided.  No need to do anything. This is the overall main method. It launches the client appli- cation.

6 What to submit?

This is part of your resit.

1.  Compress into a single  .zip  file  the three  .java  files corresponding to ResitServer.java, ResitService.java and the

ResitClient.java classes. Do not include the Credentials.java file. 2.  Submit the  .zip file into canvas.

Do NOT include the database file .sql or the postgres driver in the  .zip.

IMPORTANT: Do NOT use winrar for compressing but standard .zip.  Do ONLY zipped the afore mentioned files.  Do NOT create or organize the files into folders.  If you develop your code in some IDE, e.g.  IntelliJ, extract only the source files and do not submit the whole project.  A penalty will be applied to your marks if any repackaging is necessary at our end.

7 Sample outputs

Your outputs should match the sample outputs.

IMPORTANT: The examples below are only a necessary but not sufficient conditions to pass.  We perform additional undisclosed tests to ensure you aim for a general solution (rather as for instance, a hardcoded one). In other words, not complying with the tests below is a guarantee for failing but complying might not suffice to pass.   It is simply not possible (nor appropriate) to provide every single scenario.

7.1 Server output

All server output is reported via the console.  This combines the output of both the ResitServer.java and the ResitService.java as they together both form the server application.  An exemplary output of the server ap- plication is shown in Figure 2.   The numbers accompanying the  “Service thread” line prefixes corresponds to the thread id.  These will vary in each run.

7.2 Client output

The client output is reported via both, the GUI and the console.  An exem- plary output of the client application in the console is shown in Figure 3. The corresponding two services requests in such execution are presented in Figures 4 and 5 respectively.  Also, Figure 5 shows how the output table should look when a query returns no records.   A  console output when a query returns no records will simply be empty e.g.

Client:  Requesting  database  service  for  user  command

knife;Room  101;13:00

****  []

====================================

The lines preceded by **** list object identifiers in the outcome. These will vary in each run. It is optional to include these lines in the output.