Reference no: EM132594539
COIT20257 Distributed Systems: Principles and Development - Central Queensland University
Objective 1: Develop distributed applications using networking, inter-process communication, and remote invocation
Objective 2: Solve problems in the distributed systems domain by applying the principles of distributed systems to authentic problems
Assignment Title: A Simplified Remote Invocation Framework
The application background
Java RMI (Remote Method Invocation, reference Chapter 5 of the textbook and Week-3 lecture) enables the local invocation and remote invocation use the same syntax to implement a generic remote server like the Compute Engine example in Week-3 lecture slides. The application background of such a compute engine is to utilise the compute-power of a high-performance computer or cluster. That is, a client prepares compute-tasks and submits them to the server for execution. Java RMI framework needs two HTTP servers to transfer Java classes between an RMI client and an RMI server at runtime. In addition, Java RMI applications need an RMI Registry to register or look up the remote objects. In this assignment, you are to implement a remote invocation framework that is similar to Java RMI but lightweight (note: for this assignment, you don't use any Java RMI APIs).
Java TCP streaming, object serialization, multithreading and client/server model are the fundamental Java components to build distributed applications. These models and components have been introduced through Week 1 to Week 5 lectures, tutorials and lab projects of this unit. These models and components are enough to develop such a simplified framework of this assignment. You will need review these models and components and practise relevant lab projects of these weeks for this assignment.
This assignment specification is as follows.
Part 1: Java TCP streaming, Multithreading and Object Serialization Programming
The framework consists of a compute-server, a compute-client and a class repository, which are depicted in the following diagram. The framework is a generic computing architecture because the compute-client and compute-server just need to know the Task interface and CSMessage class as the communication contract to interact with each other via the framework. The specification of the components is as follows.
1. The interaction contract
The interaction contract between a compute-client and the compute-server consists of the
Task interface and the CSMessage class.
1. The Task interface defines two standard methods that every compute-task must implements. For example, in this assignment, three compute-tasks CalculatePi.class, CalculatePrime.class and CalculateGCD.class all implement the task interface.
package Contract; public interface Task {
public void executeTask(); public Object getResult();
}
2. The CSMessage class is a special implementation of the Task interface. The
CSMessage class is handling exceptions.
public class CSMessage implements Task, Serializable {
//The variable that holds the error information private String finalResult;
public CSMessage() {
}
//Return the error message public Object getResult() {
return finalResult;
}
//Set the error message
public void setMessage(String msg) { finalResult=msg;
}
public void executeTask() {
}
}
When there is an exception occurred (e.g. a compute-client wants the compute-server to perform a compute-task but forgets uploading the Java class of the compute-task onto the class repository of the compute-server), the compute-server creates a CSMessage object filled with the exception message and sends it back to the compute-client. By calling the getResult() method, the compute-client gets the exception message.
2. The compute-task
A compute-task must implement the Task interface. Executing the executeTask() method will perform the task and set the result. Calling the getResult() method will return the result. A compute-task must implement java.io.Serializable interface as well so that the compute-task can be transferred between the compute-server and a compute-client over the network. The structure of a compute-class is as follows.
public class CalculatePi implements Task, Serializable{
...... @Override
public void executeTask() {
//The implementation of method
......
}
@Override
public Object getResult() {
//The implementation of method
......
}
//may have other methods
......
}
Every compute-task class is defined in the compute-client and it must be uploaded to the class repository of the compute-server. Every compute-task object is created in the compute-client and submitted to the server to execute.
3. The class repository
The compute-server has a class repository that saves the Java classes of available compute-tasks. Before asking the compute-server to perform a compute-task, a compute-client must upload the Java class of the task onto the class repository. The uploading of compute-tasks is automated by the client and the server, not manually by a user.
The following screenshots show that when the compute-server starts, it is listening on two ports for object or file transfer. the class repository has no real compute-tasks except the communication contract Task interface and CSMessage class.
4. The interaction workflow of the framework
When the compute-client starts as shown in the following screenshots, the server name and ports need to be set. Clicking the Set button will:
1. Establish two TCP connections to the server on the given ports, one for object transfer and the other for file transfer.
2. Update the task drop-down list to include the available tasks.
3. Enable the Upload and Calculate buttons.
Selecting a task (e.g. Calculate Pi) and clicking the Upload button, the Java class of selected task (e.g. CalaulatePi.class) will be uploaded to the class repository of the compute-sever as shown in the following screenshots.
Clicking the Calculate button will collect the arguments for the selected task. For example, for Calculate Pi, the argument is the number of decimal places to calculate Pi for certain accuracy.
Clicking the OK button will involve the following interaction between the client and the server.
1. The client creates a CalaulatePi object and sends to the server.
2. The server receives the CalaulatePi object and cast (deserialize) the task into the
Task interface type.
3. The server calls its executeTask() method, which performs the computation and sets the result on the same object.
4. The compute-server sends the same CalaulatePi object back to the compute-client.
5. The client receives the CalaulatePi object back from the server.
6. The compute-client calls the getResult() method of the object to retrieve and display the result.
The state of the class repository, the output of the compute-client and the compute-server are shown in the following screenshots.
In the same way the compute-client can ask the compute-server to perform other tasks as shown in the following screenshots.
5. The error message
However, when there is an exception occurred, the compute-server will create a CSMessage and send to the compute-client. The following screenshots show the situation of calling the compute-server before the compute-task ComputeGCD is uploaded.
The following screenshots show the situation of calling the compute-server after the compute- task ComputeGCD is uploaded.
6. The implementation
To complete this assignment, you need to implement such a framework and integrate the Calculate Pi, Calculate Primes and Calculate the Greatest Common Divisor tasks into this framework. The algorithms of these tasks are given on the unit web site. The sample code of transferring binary files over networks has been provided on the unit web site. The compute- server must be multi-threaded and follow the ‘thread-per-connection' architecture (reference Week-4 contents). The communication between the compute-server and the compute-client must use TCP streaming by using Java TCP API Socket and ServerSocket as described in Week-2 contents of this unit. Please note: use of any other protocols will incur no marks to be awarded for this part.
To implement the framework, you need to implement the following Java classes:
1. A Java application to implement the compute-client; graphic user interface (GUI) is required. The GUI should have the necessary components to enable the user to execute all the functions as provided as in this assignment specification;
2. A Java application to implement the compute-server; and
3. A number of Java class to implement the processing threads when necessary.
Note: to demonstrate your competence of concurrency programming, you will need to make an analysis on when concurrency is needed. Marks will be deducted if concurrency is not identified or necessary multithreading is not used.
4. A number of Java classes to implement Calculate Pi, Calculate Primes and Calculate the Greatest Common Divisor tasks.
Note: to simulate compute-client and compute-server interaction, you don't have to run them on two physical machines. Instead, they can be run on two JVMs (Java Virtual Machines) on a single physical machine. As a result, the name of the server machine can be ‘localhost'.
Part 2: Program use and test instruction
After the implementation of the framework, prepare an end user' instruction about how to use your software.
Attachment:- Distributed Systems.rar