/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://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 org.apache.dubbo.remoting.http.tomcat;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.servlet.DispatcherServlet;
import org.apache.dubbo.remoting.http.servlet.ServletManager;
import org.apache.dubbo.remoting.http.support.AbstractHttpServer;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;

import java.io.File;

import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREADS;
import static org.apache.dubbo.remoting.Constants.ACCEPTS_KEY;

public class TomcatHttpServer extends AbstractHttpServer {

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

    private final Tomcat tomcat;

    private final URL url;

    public TomcatHttpServer(URL url, final HttpHandler handler) {
        super(url, handler);

        this.url = url;
        DispatcherServlet.addHttpHandler(url.getPort(), handler);
        String baseDir = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
        tomcat = new Tomcat();
        tomcat.setBaseDir(baseDir);
        tomcat.setPort(url.getPort());
        tomcat.getConnector().setProperty(
                "maxThreads", String.valueOf(url.getParameter(THREADS_KEY, DEFAULT_THREADS)));
//        tomcat.getConnector().setProperty(
//                "minSpareThreads", String.valueOf(url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS)));

        tomcat.getConnector().setProperty(
                "maxConnections", String.valueOf(url.getParameter(ACCEPTS_KEY, -1)));

        tomcat.getConnector().setProperty("URIEncoding", "UTF-8");
        tomcat.getConnector().setProperty("connectionTimeout", "60000");

        tomcat.getConnector().setProperty("maxKeepAliveRequests", "-1");
        tomcat.getConnector().setProtocol("org.apache.coyote.http11.Http11NioProtocol");

        Context context = tomcat.addContext("/", baseDir);
        Tomcat.addServlet(context, "dispatcher", new DispatcherServlet());
        context.addServletMapping("/*", "dispatcher");
        ServletManager.getInstance().addServletContext(url.getPort(), context.getServletContext());

        // tell tomcat to fail on startup failures.
        System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");

        try {
            tomcat.start();
        } catch (LifecycleException e) {
            throw new IllegalStateException("Failed to start tomcat server at " + url.getAddress(), e);
        }
    }

    @Override
    public void close() {
        super.close();

        ServletManager.getInstance().removeServletContext(url.getPort());

        try {
            tomcat.stop();
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
        }
    }
}

@@ -1306,16 +1306,64 @@
 eption;%0A
+import org.apache.catalina.connector.Connector;%0A
 import o
@@ -2159,32 +2159,33 @@
 w Tomcat();%0A
+%0A
         
 tomcat.setBa
@@ -2176,102 +2176,108 @@
     
-tomcat.setBaseDir(baseDir);%0A        tomcat.setPort(url.getPort());%0A        tomcat.getC
+Connector connector = new Connector(%22org.apache.coyote.http11.Http11NioProtocol%22);%0A        c
 onnector
 ().s
@@ -2276,129 +2276,41 @@
 ctor
-()
 .setP
-roperty(%0A                %22maxThreads%22, String.valueOf(url.getParameter(THREADS_KEY, DEFAULT_THREADS)
+ort(url.getPort(
 ));%0A
-//
         
 tomc
@@ -2305,35 +2305,25 @@
         
-tomcat.getC
+c
 onnector
 ().setPr
@@ -2306,34 +2306,32 @@
        connector
-()
 .setProperty(%0A//
@@ -2331,36 +2331,12 @@
 rty(
-%0A//                %22minSpare
+%22max
 Thre
@@ -2373,26 +2373,16 @@
 rameter(
-Constants.
 THREADS_
@@ -2386,26 +2386,16 @@
 DS_KEY, 
-Constants.
 DEFAULT_
@@ -2402,33 +2402,32 @@
 THREADS)));%0A
-%0A
         
 tomcat.getCo
@@ -2414,35 +2414,25 @@
         
-tomcat.getC
+c
 onnector
 ().setPr
@@ -2415,34 +2415,32 @@
        connector
-()
 .setProperty(%0A  
@@ -2440,25 +2440,8 @@
 rty(
-%0A                
 %22max
@@ -2506,25 +2506,24 @@
  -1)));%0A
-%0A
         
 tomcat.g
@@ -2514,35 +2514,25 @@
         
-tomcat.getC
+c
 onnector
 ().setPr
@@ -2515,34 +2515,32 @@
        connector
-()
 .setProperty(%22UR
@@ -2569,35 +2569,25 @@
         
-tomcat.getC
+c
 onnector
 ().setPr
@@ -2570,34 +2570,32 @@
        connector
-()
 .setProperty(%22co
@@ -2622,25 +2622,24 @@
 0000%22);%0A
-%0A
         
 tomcat.g
@@ -2630,35 +2630,25 @@
         
-tomcat.getC
+c
 onnector
 ().setPr
@@ -2635,26 +2635,24 @@
    connector
-()
 .setProperty
@@ -2698,17 +2698,17 @@
  tomcat.
-g
+s
 etConnec
@@ -2715,66 +2715,93 @@
 tor(
-).setProtocol(%22org.apache.coyote.http11.Http11NioProtocol%22
+connector);%0A%0A        tomcat.setBaseDir(baseDir);%0A        tomcat.setPort(url.getPort()
 );%0A%0A

fix tomcat9 support. #5711 (#6066)