cleaned and made ready task 1
This commit is contained in:
103
week3_TinsaeGhilay/Task 1/src/client/Client.java
Normal file
103
week3_TinsaeGhilay/Task 1/src/client/Client.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package client;
|
||||
|
||||
// Client/Client.java class represents the client that has to relay on the compute engine
|
||||
// to perform tasks remotely.
|
||||
// it needs the compute interface from compute package
|
||||
import compute.Compute;
|
||||
|
||||
// it also needs those to access the registry,
|
||||
// so it can get remote object reference of the server
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Client {
|
||||
private Client() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// normally, the address of the server is passed here on the command line as an
|
||||
// argument
|
||||
// we get that address from args[0] if provided, else we use null for localhost
|
||||
String host = (args.length < 1) ? null : args[0];
|
||||
String name = "Compute";
|
||||
|
||||
try (Scanner scanner = new Scanner(System.in);) {
|
||||
|
||||
// get the registry from host(server)
|
||||
Registry registry = LocateRegistry.getRegistry(host);
|
||||
|
||||
// look up the remote object by name in the registry
|
||||
// stub is the a reference to the remote object
|
||||
Compute stub = (Compute) registry.lookup(name);
|
||||
|
||||
// interactive client to perform operations
|
||||
System.out.println("Connected to ComputeEngine. Type 'exit' to quit.");
|
||||
while (true) {
|
||||
|
||||
// get user input for first number
|
||||
System.out.println("Enter first number: ");
|
||||
String input = scanner.next();
|
||||
if (input.equalsIgnoreCase("exit")) {
|
||||
System.out.println("Exiting client.");
|
||||
break;
|
||||
}
|
||||
int a = validateNumber(input);
|
||||
|
||||
// get user input for second number
|
||||
System.out.println("Enter second number: ");
|
||||
input = scanner.next();
|
||||
if (input.equalsIgnoreCase("exit")) {
|
||||
System.out.println("Exiting client.");
|
||||
break;
|
||||
}
|
||||
int b = validateNumber(input);
|
||||
|
||||
// get user input for operand
|
||||
System.out.println("Enter operand (+, -, *, /, %): ");
|
||||
input = scanner.next();
|
||||
if (input.equalsIgnoreCase("exit")) {
|
||||
System.out.println("Exiting client.");
|
||||
break;
|
||||
}
|
||||
String operand = validateOperand(input);
|
||||
|
||||
// create operation task
|
||||
Operation op = new Operation(a, b, operand);
|
||||
// execute task remotely
|
||||
int result = stub.executeTask(op);
|
||||
System.out.println("Result: " + a + " " + operand + " " + b + " = " + result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Client exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// simple validation methods. Because It is said
|
||||
// "Be conservative on what you do, be liberal on what you accept from others"
|
||||
// for int parsing
|
||||
private static int validateNumber(String a) {
|
||||
try {
|
||||
return Integer.parseInt(a);
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("Invalid number format: " + a + ". Defaulting to 0.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// For operand validation
|
||||
private static String validateOperand(String op) {
|
||||
switch (op) {
|
||||
case "+":
|
||||
case "-":
|
||||
case "*":
|
||||
case "/":
|
||||
case "%":
|
||||
return op;
|
||||
default:
|
||||
System.err.println("Invalid operand: " + op + ". Defaulting to '+'.");
|
||||
return "+";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,24 @@
|
||||
package org.distributed.engine;
|
||||
|
||||
public class Operation implements Task<Integer> {
|
||||
package client;
|
||||
|
||||
int a,b;
|
||||
import java.io.Serializable;
|
||||
import compute.Task;
|
||||
|
||||
public class Operation implements Task<Integer>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
int a, b;
|
||||
String operand;
|
||||
|
||||
public Operation(int a, int b, String operand){
|
||||
public Operation(int a, int b, String operand) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.operand = operand;
|
||||
|
||||
}
|
||||
|
||||
// do the operation
|
||||
public Integer execute() {
|
||||
return switch (this.operand) {
|
||||
case "+" -> a + b;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.distributed.engine;
|
||||
package compute;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
@@ -8,5 +8,5 @@ import java.rmi.RemoteException;
|
||||
public interface Compute extends Remote {
|
||||
|
||||
// needs a task interface
|
||||
int executeTask(Operation t) throws RemoteException;
|
||||
<T> T executeTask(Task<T> t) throws RemoteException;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.distributed.compute;
|
||||
package compute;
|
||||
|
||||
/**
|
||||
* This interface is the type of parameter to the executeTask() method of the
|
||||
58
week3_TinsaeGhilay/Task 1/src/engine/ComputeEngine.java
Normal file
58
week3_TinsaeGhilay/Task 1/src/engine/ComputeEngine.java
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
package engine;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
// needs the compute and task interfaces from compute package
|
||||
// define constructor for each
|
||||
// and provide an implementation for each remote method in the remote interfaces
|
||||
import compute.Compute;
|
||||
import compute.Task;
|
||||
|
||||
/**
|
||||
* The implementation of the Compute interface for the compute engine.
|
||||
* it has to declare the remote class to be implemented (in this case Compute
|
||||
* (implements it)
|
||||
*/
|
||||
public class ComputeEngine implements Compute {
|
||||
|
||||
public ComputeEngine() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T executeTask(Task<T> t) throws RemoteException {
|
||||
return t.execute();
|
||||
}
|
||||
|
||||
// entry
|
||||
public static void main(String[] args) {
|
||||
|
||||
// the code provided on the tutorial was deprecated.
|
||||
// so google led me to
|
||||
// [this](https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/hello/hello-world.html#create)
|
||||
try {
|
||||
String name = "Compute";
|
||||
// create remote object that provides service (server).
|
||||
Compute engine = new ComputeEngine();
|
||||
|
||||
// and export remote object to java RMI runtime
|
||||
// so it may receive remote incoming calls
|
||||
Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);
|
||||
|
||||
// the register the remote object with java RMI registry
|
||||
// the registry is a name service that allows clients get a reference of remote
|
||||
// objects
|
||||
// once a remote object is registered, callers can look up the object by name
|
||||
// and obtain its remote object reference
|
||||
Registry registry = LocateRegistry.getRegistry();
|
||||
registry.rebind(name, stub);
|
||||
System.out.println("ComputeEngine bound");
|
||||
} catch (Exception e) {
|
||||
System.err.println("ComputeEngine exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package org.distributed.client;
|
||||
|
||||
public class Client {
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.distributed;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class ComputeEngine implements Compute {
|
||||
|
||||
public ComputeEngine() {
|
||||
super();
|
||||
}
|
||||
@Override
|
||||
public <T> T executeTask(Task<T> t) throws RemoteException {
|
||||
return t.execute();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user