
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());
        }
    }
}
