DS-Lab / src / main / java / dslab / mailbox / MailboxServer.java
MailboxServer.java
Raw
package dslab.mailbox;

import at.ac.tuwien.dsg.orvell.StopShellException;
import at.ac.tuwien.dsg.orvell.annotation.Command;
import dslab.ComponentFactory;
import dslab.protocol.dmap.Dmap;
import dslab.protocol.dmtp.Dmtp;
import dslab.rmi.stub.dmap.DmapServerStub;
import dslab.rmi.stub.dmtp.DmtpServerStub;
import dslab.threading.Dispatcher;

import java.io.InputStream;
import java.io.PrintStream;
import java.util.logging.Logger;

public class MailboxServer implements IMailboxServer, Runnable {

    private static final Logger LOG = Logger.getLogger(MailboxServer.class.getSimpleName());
    private final Dispatcher<Dmtp> dmtpDispatcher;
    private final Dispatcher<Dmap> dmapDispatcher;
    private final InputStream in;
    private final PrintStream out;
    private final ComponentFactory cf;


    public MailboxServer(ComponentFactory componentFactory, InputStream in, PrintStream out) {
        this.in = in;
        this.out = out;
        this.cf = componentFactory;

        var mboxConfig = cf.getMailboxServerConfig();

        try {
            cf.getRootNameserverRemote().registerMailboxServer(
                    mboxConfig.domain(), mboxConfig.address() + ":" + mboxConfig.dmtpTcpPort());
        } catch (Exception e){
            // Assignment text: "Make sure that your mailbox servers functions
            // even if the registry can’t be located or an error occurs."
            LOG.warning("Could not register with nameserver. Only local delivery of messages will be available. " +
                        "Reason: " + e.getMessage());
        }

        dmtpDispatcher = new Dispatcher<>(
                mboxConfig.dmtpTcpPort(),
                channel -> new DmtpServerStub(channel, cf.getDeliveryService()),
                Dmtp.class.getSimpleName(), cf);

        dmapDispatcher = new Dispatcher<>(
                mboxConfig.dmapTcpPort(),
                socket -> new DmapServerStub(
                        socket,
                        cf.getAuthenticationService(),
                        cf.getMailboxManager()),
                Dmap.class.getSimpleName(), cf);
    }

    @Override
    public void run() {
        dmtpDispatcher.start();
        dmapDispatcher.start();
        cf.createShell(this, in, out).run();
    }

    @Override @Command
    public void shutdown() {
        LOG.info(cf.getComponentId() + " received shutdown command.");
        dmapDispatcher.interrupt();
        dmtpDispatcher.interrupt();
        try {
            dmtpDispatcher.join();
            dmapDispatcher.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        cf.shutdown();
        throw new StopShellException();
    }

    public static void main(String[] args) throws Exception {
        IMailboxServer server = ComponentFactory.createMailboxServer(args[0], System.in, System.out);
        server.run();
    }

    public ComponentFactory getComponentFactory() {
        return cf;
    }
}