Package restx.server

Source Code of restx.server.TomcatWebServer

package restx.server;

import com.google.common.base.Throwables;
import com.google.common.eventbus.EventBus;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import restx.common.MoreFiles;
import restx.common.MoreIO;
import restx.common.Version;

import javax.servlet.ServletException;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.atomic.AtomicLong;

import static restx.common.MoreFiles.checkFileExists;
import static restx.common.MoreIO.checkCanOpenSocket;

/**
* TomcatWebServer allow to run embedded tomcat. But its startup time is much slower than JettyWebServer.
*/
public class TomcatWebServer implements WebServer {
    private static final AtomicLong SERVER_ID = new AtomicLong();

    private final static Logger logger = LoggerFactory.getLogger(TomcatWebServer.class);

    private final Tomcat tomcat;
    private final String appBase;
    private final int port;
    private String serverId;
    private final Context context;

    public TomcatWebServer(String appBase, int port) throws ServletException {
        checkFileExists(appBase);
        this.appBase = appBase;
        this.port = port;
        this.serverId = "Tomcat#" + SERVER_ID.incrementAndGet();
        tomcat = new Tomcat();
        tomcat.setPort(port);

        tomcat.setBaseDir(".");
        tomcat.getHost().setAppBase(".");

        String contextPath = "/";

        // Add AprLifecycleListener
        StandardServer server = (StandardServer) tomcat.getServer();
        AprLifecycleListener listener = new AprLifecycleListener();
        server.addLifecycleListener(listener);

        context = tomcat.addWebapp(contextPath, appBase);
    }

    /**
     * Sets the serverId used by this server.
     *
     * Must not be called when server is started.
     *
     * The serverId is used to uniquely identify the main Factory used by REST main router in this server.
     * It allows to access the Factory with Factory.getInstance(serverId).
     *
     * @param serverId the server id to set. Must be unique in the JVM.
     *
     * @return current server
     */
    public synchronized TomcatWebServer setServerId(final String serverId) {
        if (isStarted()) {
            throw new IllegalStateException("can't set server id when server is started");
        }
        this.serverId = serverId;
        return this;
    }

    @Override
    public String getServerId() {
        return serverId;
    }

    @Override
    public int getPort() {
        return port;
    }

    @Override
    public String baseUrl() {
        return WebServers.baseUri("localhost", port);
    }

    @Override
    public String getServerType() {
        return "Apache Tomcat " + Version.getVersion("org.apache.tomcat", "tomcat-catalina") + ", embedded";
    }

    @Override
    public synchronized void start() throws LifecycleException {
        context.getServletContext().setInitParameter("restx.baseServerUri", baseUrl());
        context.getServletContext().setInitParameter("restx.serverId", serverId);
        checkCanOpenSocket(port);
        WebServers.register(this);
        tomcat.start();
    }

    @Override
    public void startAndAwait() throws LifecycleException {
        start();
        await();
    }

    @Override
    public void await() {
        tomcat.getServer().await();
    }


    public synchronized void stop() throws LifecycleException {
        tomcat.stop();
        WebServers.unregister(serverId);
    }

    @Override
    public synchronized boolean isStarted() {
        return WebServers.getServerById(serverId).isPresent();
    }

    public static WebServerSupplier tomcatWebServerSupplier(final String appBase) {
        return new WebServerSupplier() {
            @Override
            public WebServer newWebServer(int port) {
                try {
                    return new TomcatWebServer(appBase, port);
                } catch (ServletException e) {
                    throw Throwables.propagate(e);
                }
            }
        };
    }

}
TOP

Related Classes of restx.server.TomcatWebServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.