All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.elsci.mocks.web.tomcat.EmbeddedTomcat Maven / Gradle / Ivy

There is a newer version: 20231025.1145-36
Show newest version
package io.elsci.mocks.web.tomcat;

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.AbstractProtocol;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.threads.TaskQueue;
import org.apache.tomcat.util.threads.TaskThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.filter.ForwardedHeaderFilter;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static io.elsci.mocks.web.tomcat.TomcatProperties.DAEMON;
import static io.elsci.mocks.web.tomcat.TomcatProperties.THREAD_PRIORITY;
import static java.util.Collections.emptyMap;

public class EmbeddedTomcat {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedTomcat.class);
    private static final int KEEP_ALIVE_TIME = 60;
    private static final String SPRING_DISPATCHER = "spring-dispatcher";
    private static final String DISPATCHER_SERVLET_CLASS = "org.springframework.web.servlet.DispatcherServlet";

    private final Tomcat tomcat;

    private final Context context;

    public EmbeddedTomcat(String springConfigurationLocation) {
        this(springConfigurationLocation, TomcatProperties.fromSystemProperties());
    }

    public EmbeddedTomcat(String springConfigurationLocation, TomcatProperties properties) {
        tomcat = new Tomcat();
        tomcat.setBaseDir(properties.getBaseDirPath());
        context = tomcat.addContext(properties.getContextPath(), null);
        context.setSessionTimeout(properties.getSessionTimeoutMin());
        tomcat.setConnector(createConnector(properties));

        addSpringContext(springConfigurationLocation);

        addFilter(CharacterEncodingFilter.class, "encodingFilter", Map.of("encoding", StandardCharsets.UTF_8.name()));
        addFilter(ForwardedHeaderFilter.class, "forwardedHeaderFilter", emptyMap());
//        addFilter(DelegatingFilterProxy.class, "springSecurityFilterChain", emptyMap());
    }

    private void addFilter(Class filterClass, String filterName, Map params) {
        FilterDef filterDef = new FilterDef();
        filterDef.setFilterClass(filterClass.getName());
        filterDef.setFilterName(filterName);
        params.forEach(filterDef::addInitParameter);

        context.addFilterDef(filterDef);

        FilterMap filterMap = new FilterMap();
        filterMap.setFilterName(filterName);
        filterMap.addURLPattern("/*");

        context.addFilterMap(filterMap);
    }

    private void addSpringContext(String contextConfigLocation) {
        Container springContext = context.findChild(SPRING_DISPATCHER);

        if (springContext == null) {
            Wrapper spring = context.createWrapper();

            spring.setName(SPRING_DISPATCHER);
            spring.setServletClass(DISPATCHER_SERVLET_CLASS);
            spring.addInitParameter("contextConfigLocation", contextConfigLocation);
            spring.setLoadOnStartup(1);

            context.addChild(spring);
            context.addServletMappingDecoded("/", SPRING_DISPATCHER);
        }
    }

    public void startServer() {
        try {
            tomcat.start();
            tomcat.getServer().await();
        } catch (LifecycleException e) {
            LOGGER.error("Can't start Tomcat", e);
            throw new RuntimeException(e);
        }
    }

    private Connector createConnector(TomcatProperties properties) {
        Connector connector = new Connector();
        connector.setPort(properties.getPort());
        AbstractProtocol protocolHandler = (AbstractProtocol) connector.getProtocolHandler();
        protocolHandler.setExecutor(createExecutor(properties));

        return connector;
    }

    private Executor createExecutor(TomcatProperties properties) {
        TaskThreadFactory tf = new TaskThreadFactory(properties.getThreadPrefix(), DAEMON, THREAD_PRIORITY);
        return new ThreadPoolExecutor(properties.getMinThreads(), properties.getMaxThreads(), KEEP_ALIVE_TIME,
                TimeUnit.SECONDS, new TaskQueue(), tf);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy