More bug fix and refactoring
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / ProvServer.java
diff --git a/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/ProvServer.java b/datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/ProvServer.java
new file mode 100644 (file)
index 0000000..c0e6b8d
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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
+ *
+ *      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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.datarouter.provisioning;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.security.Security;
+import java.util.EnumSet;
+import java.util.Properties;
+import javax.servlet.DispatcherType;
+import javax.servlet.ServletException;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.jetbrains.annotations.NotNull;
+import org.onap.dmaap.datarouter.provisioning.utils.AafPropsUtils;
+import org.onap.dmaap.datarouter.provisioning.utils.DRProvCadiFilter;
+import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
+
+
+public class ProvServer {
+
+    public static final EELFLogger intlogger = EELFManager.getInstance()
+        .getLogger("InternalLog");
+
+    private static Server server;
+
+    private ProvServer() {
+    }
+
+    static Server getServerInstance() {
+        if (server == null) {
+            server = createProvServer(ProvRunner.getProvProperties());
+        }
+        return server;
+    }
+
+    private static Server createProvServer(Properties provProps) {
+        final int httpsPort = Integer.parseInt(
+            provProps.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
+
+        Security.setProperty("networkaddress.cache.ttl", "4");
+        QueuedThreadPool queuedThreadPool = getQueuedThreadPool();
+
+        server = new Server(queuedThreadPool);
+        server.setStopAtShutdown(true);
+        server.setStopTimeout(5000);
+        server.setDumpAfterStart(false);
+        server.setDumpBeforeStop(false);
+
+        NCSARequestLog ncsaRequestLog = getRequestLog(provProps);
+        RequestLogHandler requestLogHandler = new RequestLogHandler();
+        requestLogHandler.setRequestLog(ncsaRequestLog);
+
+        server.setRequestLog(ncsaRequestLog);
+
+        HttpConfiguration httpConfiguration = getHttpConfiguration(httpsPort);
+
+        //HTTP Connector
+        try (ServerConnector httpServerConnector = new ServerConnector(server,
+            new HttpConnectionFactory(httpConfiguration))) {
+            httpServerConnector.setPort(Integer.parseInt(provProps.getProperty(
+                "org.onap.dmaap.datarouter.provserver.http.port", "8080")));
+            httpServerConnector.setAcceptQueueSize(2);
+            httpServerConnector.setIdleTimeout(30000);
+
+            SslContextFactory sslContextFactory = getSslContextFactory(provProps);
+
+            // HTTPS configuration
+            HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
+            httpsConfiguration.setRequestHeaderSize(8192);
+
+            // HTTPS connector
+            try (ServerConnector httpsServerConnector = new ServerConnector(server,
+                new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+                new HttpConnectionFactory(httpsConfiguration))) {
+                httpsServerConnector.setPort(httpsPort);
+                httpsServerConnector.setIdleTimeout(30000);
+                httpsServerConnector.setAcceptQueueSize(2);
+
+                ServletContextHandler servletContextHandler = getServletContextHandler(provProps);
+                ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
+                contextHandlerCollection.addHandler(servletContextHandler);
+
+                // Server's Handler collection
+                HandlerCollection handlerCollection = new HandlerCollection();
+                handlerCollection.setHandlers(new Handler[]{contextHandlerCollection, new DefaultHandler()});
+                handlerCollection.addHandler(requestLogHandler);
+
+                server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
+                server.setHandler(handlerCollection);
+            }
+        }
+        return server;
+    }
+
+    @NotNull
+    private static QueuedThreadPool getQueuedThreadPool() {
+        // Server's thread pool
+        QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
+        queuedThreadPool.setMinThreads(10);
+        queuedThreadPool.setMaxThreads(200);
+        queuedThreadPool.setDetailedDump(false);
+        return queuedThreadPool;
+    }
+
+    @NotNull
+    private static SslContextFactory getSslContextFactory(Properties provProps) {
+        SslContextFactory sslContextFactory = new SslContextFactory();
+        sslContextFactory.setKeyStoreType(AafPropsUtils.KEYSTORE_TYPE_PROPERTY);
+        sslContextFactory.setKeyStorePath(ProvRunner.getAafPropsUtils().getKeystorePathProperty());
+        sslContextFactory.setKeyStorePassword(ProvRunner.getAafPropsUtils().getKeystorePassProperty());
+        sslContextFactory.setKeyManagerPassword(ProvRunner.getAafPropsUtils().getKeystorePassProperty());
+
+        sslContextFactory.setTrustStoreType(AafPropsUtils.TRUESTSTORE_TYPE_PROPERTY);
+        sslContextFactory.setTrustStorePath(ProvRunner.getAafPropsUtils().getTruststorePathProperty());
+        sslContextFactory.setTrustStorePassword(ProvRunner.getAafPropsUtils().getTruststorePassProperty());
+
+        sslContextFactory.setWantClientAuth(true);
+        sslContextFactory.setExcludeCipherSuites(
+            "SSL_RSA_WITH_DES_CBC_SHA",
+            "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+            "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+            "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+            "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+        );
+        sslContextFactory.addExcludeProtocols("SSLv3");
+        sslContextFactory.setIncludeProtocols(provProps.getProperty(
+            "org.onap.dmaap.datarouter.provserver.https.include.protocols",
+            "TLSv1.1|TLSv1.2").trim().split("\\|"));
+
+        intlogger.info("Unsupported protocols: " + String.join(",", sslContextFactory.getExcludeProtocols()));
+        intlogger.info("Supported protocols: " + String.join(",", sslContextFactory.getIncludeProtocols()));
+        intlogger.info("Unsupported ciphers: " + String.join(",", sslContextFactory.getExcludeCipherSuites()));
+        intlogger.info("Supported ciphers: " + String.join(",", sslContextFactory.getIncludeCipherSuites()));
+
+        return sslContextFactory;
+    }
+
+    @NotNull
+    private static NCSARequestLog getRequestLog(Properties provProps) {
+        NCSARequestLog ncsaRequestLog = new NCSARequestLog();
+        ncsaRequestLog.setFilename(provProps.getProperty(
+            "org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");
+        ncsaRequestLog.setFilenameDateFormat("yyyyMMdd");
+        ncsaRequestLog.setRetainDays(90);
+        ncsaRequestLog.setAppend(true);
+        ncsaRequestLog.setExtended(false);
+        ncsaRequestLog.setLogCookies(false);
+        ncsaRequestLog.setLogTimeZone("GMT");
+        return ncsaRequestLog;
+    }
+
+    @NotNull
+    private static HttpConfiguration getHttpConfiguration(int httpsPort) {
+        HttpConfiguration httpConfiguration = new HttpConfiguration();
+        httpConfiguration.setSecureScheme("https");
+        httpConfiguration.setSecurePort(httpsPort);
+        httpConfiguration.setOutputBufferSize(32768);
+        httpConfiguration.setRequestHeaderSize(8192);
+        httpConfiguration.setResponseHeaderSize(8192);
+        httpConfiguration.setSendServerVersion(true);
+        httpConfiguration.setSendDateHeader(false);
+        return httpConfiguration;
+    }
+
+    @NotNull
+    private static ServletContextHandler getServletContextHandler(Properties provProps) {
+        ServletContextHandler servletContextHandler = new ServletContextHandler(0);
+        servletContextHandler.setContextPath("/");
+        servletContextHandler.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
+        servletContextHandler.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
+        servletContextHandler.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
+        servletContextHandler.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
+        servletContextHandler.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
+        servletContextHandler.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
+        servletContextHandler.addServlet(new ServletHolder(new GroupServlet()), "/group/*");
+        servletContextHandler.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
+        servletContextHandler.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
+        servletContextHandler.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
+        servletContextHandler.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
+        servletContextHandler.addFilter(new FilterHolder(new ThrottleFilter()),
+            "/publish/*", EnumSet.of(DispatcherType.REQUEST));
+        setCadiFilter(servletContextHandler, provProps);
+        return servletContextHandler;
+    }
+
+    private static void setCadiFilter(ServletContextHandler servletContextHandler, Properties provProps) {
+        if (Boolean.parseBoolean(provProps.getProperty(
+            "org.onap.dmaap.datarouter.provserver.cadi.enabled", "false"))) {
+            try {
+                servletContextHandler.addFilter(new FilterHolder(new DRProvCadiFilter(
+                    true, ProvRunner.getAafPropsUtils().getPropAccess())), "/*", EnumSet.of(DispatcherType.REQUEST));
+                intlogger.info("PROV0001 AAF CADI filter enabled");
+            } catch (ServletException e) {
+                intlogger.error("PROV0001 Failed to add CADI filter to server");
+            }
+
+        }
+    }
+}