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

io.micronaut.servlet.tomcat.TomcatFactory Maven / Gradle / Ivy

/*
 * Copyright 2017-2020 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.servlet.tomcat;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Primary;
import io.micronaut.context.env.Environment;
import io.micronaut.core.io.ResourceResolver;
import io.micronaut.core.io.socket.SocketUtils;
import io.micronaut.http.ssl.SslConfiguration;
import io.micronaut.servlet.engine.DefaultMicronautServlet;
import io.micronaut.servlet.engine.MicronautServletConfiguration;
import io.micronaut.servlet.engine.server.ServletServerFactory;
import io.micronaut.servlet.engine.server.ServletStaticResourceConfiguration;
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;

import javax.inject.Singleton;
import java.io.File;
import java.net.URL;
import java.util.List;

/**
 * Factory for the {@link Tomcat} instance.
 *
 * @author graemerocher
 * @since 1.0.0
 */
@Factory
public class TomcatFactory extends ServletServerFactory {

    static {
        TomcatURLStreamHandlerFactory.disable();
    }

    /**
     * Default constructor.
     *
     * @param resourceResolver             The resource resolver
     * @param serverConfiguration          The server config
     * @param sslConfiguration             The SSL config
     * @param applicationContext           The app context
     * @param staticResourceConfigurations The static resource configs
     */
    protected TomcatFactory(
            ResourceResolver resourceResolver,
            TomcatConfiguration serverConfiguration,
            SslConfiguration sslConfiguration,
            ApplicationContext applicationContext,
            List staticResourceConfigurations) {
        super(resourceResolver, serverConfiguration, sslConfiguration, applicationContext, staticResourceConfigurations);
    }

    @Override
    public TomcatConfiguration getServerConfiguration() {
        return (TomcatConfiguration) super.getServerConfiguration();
    }

    /**
     * The Tomcat server bean.
     *
     * @param connector The connector
     * @param configuration The servlet configuration
     * @return The Tomcat server
     */
    @Singleton
    @Primary
    protected Tomcat tomcatServer(Connector connector, MicronautServletConfiguration configuration) {
        Tomcat tomcat = new Tomcat();
        tomcat.setHostname(getConfiguredHost());
        final String contextPath = getContextPath();
        tomcat.getHost().setAutoDeploy(false);
        tomcat.setConnector(connector);
        final String cp = contextPath != null && !contextPath.equals("/") ? contextPath : "";
        final Context context = tomcat.addContext(cp, "/");
        final Wrapper servlet = Tomcat.addServlet(
                context,
                configuration.getName(),
                new DefaultMicronautServlet(getApplicationContext())
        );
        servlet.addMapping(configuration.getMapping());
        configuration.getMultipartConfigElement()
                .ifPresent(servlet::setMultipartConfigElement);

        SslConfiguration sslConfiguration = getSslConfiguration();
        if (sslConfiguration.isEnabled()) {
            String protocol = sslConfiguration.getProtocol().orElse("TLS");
            int sslPort = sslConfiguration.getPort();
            if (sslPort == SslConfiguration.DEFAULT_PORT && getEnvironment().getActiveNames().contains(Environment.TEST)) {
                sslPort = SocketUtils.findAvailableTcpPort();
            }
            Connector httpsConnector = new Connector();
            httpsConnector.setPort(sslPort);
            httpsConnector.setSecure(true);
            httpsConnector.setScheme("https");
            httpsConnector.setProperty("clientAuth", "false");
            httpsConnector.setProperty("sslProtocol", protocol);
            httpsConnector.setProperty("SSLEnabled", "true");
            sslConfiguration.getCiphers().ifPresent(cyphers -> httpsConnector.setAttribute("cyphers", cyphers));
            sslConfiguration.getClientAuthentication().ifPresent(ca -> {
                switch (ca) {
                    case WANT:
                        httpsConnector.setProperty("clientAuth", "want");
                        break;
                    default:
                    case NEED:
                        httpsConnector.setProperty("clientAuth", "true");
                        break;

                }
            });


            SslConfiguration.KeyStoreConfiguration keyStoreConfig = sslConfiguration.getKeyStore();
            keyStoreConfig.getPassword().ifPresent(s ->
                    httpsConnector.setProperty("keystorePass", s)
            );
            keyStoreConfig.getPath().ifPresent(path ->
                    setPathAttribute(httpsConnector, "keystoreFile", path)
            );
            keyStoreConfig.getProvider().ifPresent(provider ->
                    httpsConnector.setProperty("keystoreProvider", provider)
            );
            keyStoreConfig.getType().ifPresent(type ->
                    httpsConnector.setProperty("keystoreType", type)
            );

            SslConfiguration.TrustStoreConfiguration trustStore = sslConfiguration.getTrustStore();
            trustStore.getPassword().ifPresent(s ->
                    httpsConnector.setProperty("truststorePass", s)
            );
            trustStore.getPath().ifPresent(path ->
                    setPathAttribute(httpsConnector, "truststoreFile", path)
            );
            trustStore.getProvider().ifPresent(provider ->
                    httpsConnector.setProperty("truststoreProvider", provider)
            );
            trustStore.getType().ifPresent(type ->
                    httpsConnector.setProperty("truststoreType", type)
            );


            SslConfiguration.KeyConfiguration keyConfig = sslConfiguration.getKey();

            keyConfig.getAlias().ifPresent(s -> httpsConnector.setProperty("keyAlias", s));
            keyConfig.getPassword().ifPresent(s -> httpsConnector.setProperty("keyPass", s));

            tomcat.getService().addConnector(httpsConnector);
        }

        return tomcat;
    }

    /**
     * @return Create the protocol.
     */
    @Singleton
    @Primary
    protected Connector tomcatConnector() {
        final Connector tomcatConnector = getServerConfiguration().getTomcatConnector();
        tomcatConnector.setPort(getConfiguredPort());
        return tomcatConnector;
    }

    private void setPathAttribute(Connector httpsConnector, String attributeName, String path) {
        if (path.startsWith(ServletStaticResourceConfiguration.CLASSPATH_PREFIX)) {
            String res = path.substring(ServletStaticResourceConfiguration.CLASSPATH_PREFIX.length());
            URL resource = getEnvironment().getClassLoader().getResource(res);
            if (resource != null) {
                httpsConnector.setProperty(attributeName, resource.toString());
            }
        } else if (path.startsWith(ServletStaticResourceConfiguration.FILE_PREFIX)) {
            String res = path.substring(ServletStaticResourceConfiguration.FILE_PREFIX.length());
            httpsConnector.setProperty(attributeName, new File(res).getAbsolutePath());
        } else {
            httpsConnector.setProperty(attributeName, new File(path).getAbsolutePath());
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy