More bug fix and refactoring
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / ProvServer.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.dmaap.datarouter.provisioning;
22
23 import com.att.eelf.configuration.EELFLogger;
24 import com.att.eelf.configuration.EELFManager;
25 import java.security.Security;
26 import java.util.EnumSet;
27 import java.util.Properties;
28 import javax.servlet.DispatcherType;
29 import javax.servlet.ServletException;
30 import org.eclipse.jetty.http.HttpVersion;
31 import org.eclipse.jetty.server.Connector;
32 import org.eclipse.jetty.server.Handler;
33 import org.eclipse.jetty.server.HttpConfiguration;
34 import org.eclipse.jetty.server.HttpConnectionFactory;
35 import org.eclipse.jetty.server.NCSARequestLog;
36 import org.eclipse.jetty.server.Server;
37 import org.eclipse.jetty.server.ServerConnector;
38 import org.eclipse.jetty.server.SslConnectionFactory;
39 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
40 import org.eclipse.jetty.server.handler.DefaultHandler;
41 import org.eclipse.jetty.server.handler.HandlerCollection;
42 import org.eclipse.jetty.server.handler.RequestLogHandler;
43 import org.eclipse.jetty.servlet.FilterHolder;
44 import org.eclipse.jetty.servlet.ServletContextHandler;
45 import org.eclipse.jetty.servlet.ServletHolder;
46 import org.eclipse.jetty.util.ssl.SslContextFactory;
47 import org.eclipse.jetty.util.thread.QueuedThreadPool;
48 import org.jetbrains.annotations.NotNull;
49 import org.onap.dmaap.datarouter.provisioning.utils.AafPropsUtils;
50 import org.onap.dmaap.datarouter.provisioning.utils.DRProvCadiFilter;
51 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
52
53
54 public class ProvServer {
55
56     public static final EELFLogger intlogger = EELFManager.getInstance()
57         .getLogger("InternalLog");
58
59     private static Server server;
60
61     private ProvServer() {
62     }
63
64     static Server getServerInstance() {
65         if (server == null) {
66             server = createProvServer(ProvRunner.getProvProperties());
67         }
68         return server;
69     }
70
71     private static Server createProvServer(Properties provProps) {
72         final int httpsPort = Integer.parseInt(
73             provProps.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
74
75         Security.setProperty("networkaddress.cache.ttl", "4");
76         QueuedThreadPool queuedThreadPool = getQueuedThreadPool();
77
78         server = new Server(queuedThreadPool);
79         server.setStopAtShutdown(true);
80         server.setStopTimeout(5000);
81         server.setDumpAfterStart(false);
82         server.setDumpBeforeStop(false);
83
84         NCSARequestLog ncsaRequestLog = getRequestLog(provProps);
85         RequestLogHandler requestLogHandler = new RequestLogHandler();
86         requestLogHandler.setRequestLog(ncsaRequestLog);
87
88         server.setRequestLog(ncsaRequestLog);
89
90         HttpConfiguration httpConfiguration = getHttpConfiguration(httpsPort);
91
92         //HTTP Connector
93         try (ServerConnector httpServerConnector = new ServerConnector(server,
94             new HttpConnectionFactory(httpConfiguration))) {
95             httpServerConnector.setPort(Integer.parseInt(provProps.getProperty(
96                 "org.onap.dmaap.datarouter.provserver.http.port", "8080")));
97             httpServerConnector.setAcceptQueueSize(2);
98             httpServerConnector.setIdleTimeout(30000);
99
100             SslContextFactory sslContextFactory = getSslContextFactory(provProps);
101
102             // HTTPS configuration
103             HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
104             httpsConfiguration.setRequestHeaderSize(8192);
105
106             // HTTPS connector
107             try (ServerConnector httpsServerConnector = new ServerConnector(server,
108                 new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
109                 new HttpConnectionFactory(httpsConfiguration))) {
110                 httpsServerConnector.setPort(httpsPort);
111                 httpsServerConnector.setIdleTimeout(30000);
112                 httpsServerConnector.setAcceptQueueSize(2);
113
114                 ServletContextHandler servletContextHandler = getServletContextHandler(provProps);
115                 ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
116                 contextHandlerCollection.addHandler(servletContextHandler);
117
118                 // Server's Handler collection
119                 HandlerCollection handlerCollection = new HandlerCollection();
120                 handlerCollection.setHandlers(new Handler[]{contextHandlerCollection, new DefaultHandler()});
121                 handlerCollection.addHandler(requestLogHandler);
122
123                 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
124                 server.setHandler(handlerCollection);
125             }
126         }
127         return server;
128     }
129
130     @NotNull
131     private static QueuedThreadPool getQueuedThreadPool() {
132         // Server's thread pool
133         QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
134         queuedThreadPool.setMinThreads(10);
135         queuedThreadPool.setMaxThreads(200);
136         queuedThreadPool.setDetailedDump(false);
137         return queuedThreadPool;
138     }
139
140     @NotNull
141     private static SslContextFactory getSslContextFactory(Properties provProps) {
142         SslContextFactory sslContextFactory = new SslContextFactory();
143         sslContextFactory.setKeyStoreType(AafPropsUtils.KEYSTORE_TYPE_PROPERTY);
144         sslContextFactory.setKeyStorePath(ProvRunner.getAafPropsUtils().getKeystorePathProperty());
145         sslContextFactory.setKeyStorePassword(ProvRunner.getAafPropsUtils().getKeystorePassProperty());
146         sslContextFactory.setKeyManagerPassword(ProvRunner.getAafPropsUtils().getKeystorePassProperty());
147
148         sslContextFactory.setTrustStoreType(AafPropsUtils.TRUESTSTORE_TYPE_PROPERTY);
149         sslContextFactory.setTrustStorePath(ProvRunner.getAafPropsUtils().getTruststorePathProperty());
150         sslContextFactory.setTrustStorePassword(ProvRunner.getAafPropsUtils().getTruststorePassProperty());
151
152         sslContextFactory.setWantClientAuth(true);
153         sslContextFactory.setExcludeCipherSuites(
154             "SSL_RSA_WITH_DES_CBC_SHA",
155             "SSL_DHE_RSA_WITH_DES_CBC_SHA",
156             "SSL_DHE_DSS_WITH_DES_CBC_SHA",
157             "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
158             "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
159             "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
160             "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
161         );
162         sslContextFactory.addExcludeProtocols("SSLv3");
163         sslContextFactory.setIncludeProtocols(provProps.getProperty(
164             "org.onap.dmaap.datarouter.provserver.https.include.protocols",
165             "TLSv1.1|TLSv1.2").trim().split("\\|"));
166
167         intlogger.info("Unsupported protocols: " + String.join(",", sslContextFactory.getExcludeProtocols()));
168         intlogger.info("Supported protocols: " + String.join(",", sslContextFactory.getIncludeProtocols()));
169         intlogger.info("Unsupported ciphers: " + String.join(",", sslContextFactory.getExcludeCipherSuites()));
170         intlogger.info("Supported ciphers: " + String.join(",", sslContextFactory.getIncludeCipherSuites()));
171
172         return sslContextFactory;
173     }
174
175     @NotNull
176     private static NCSARequestLog getRequestLog(Properties provProps) {
177         NCSARequestLog ncsaRequestLog = new NCSARequestLog();
178         ncsaRequestLog.setFilename(provProps.getProperty(
179             "org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");
180         ncsaRequestLog.setFilenameDateFormat("yyyyMMdd");
181         ncsaRequestLog.setRetainDays(90);
182         ncsaRequestLog.setAppend(true);
183         ncsaRequestLog.setExtended(false);
184         ncsaRequestLog.setLogCookies(false);
185         ncsaRequestLog.setLogTimeZone("GMT");
186         return ncsaRequestLog;
187     }
188
189     @NotNull
190     private static HttpConfiguration getHttpConfiguration(int httpsPort) {
191         HttpConfiguration httpConfiguration = new HttpConfiguration();
192         httpConfiguration.setSecureScheme("https");
193         httpConfiguration.setSecurePort(httpsPort);
194         httpConfiguration.setOutputBufferSize(32768);
195         httpConfiguration.setRequestHeaderSize(8192);
196         httpConfiguration.setResponseHeaderSize(8192);
197         httpConfiguration.setSendServerVersion(true);
198         httpConfiguration.setSendDateHeader(false);
199         return httpConfiguration;
200     }
201
202     @NotNull
203     private static ServletContextHandler getServletContextHandler(Properties provProps) {
204         ServletContextHandler servletContextHandler = new ServletContextHandler(0);
205         servletContextHandler.setContextPath("/");
206         servletContextHandler.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
207         servletContextHandler.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
208         servletContextHandler.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
209         servletContextHandler.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
210         servletContextHandler.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
211         servletContextHandler.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
212         servletContextHandler.addServlet(new ServletHolder(new GroupServlet()), "/group/*");
213         servletContextHandler.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
214         servletContextHandler.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
215         servletContextHandler.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
216         servletContextHandler.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
217         servletContextHandler.addFilter(new FilterHolder(new ThrottleFilter()),
218             "/publish/*", EnumSet.of(DispatcherType.REQUEST));
219         setCadiFilter(servletContextHandler, provProps);
220         return servletContextHandler;
221     }
222
223     private static void setCadiFilter(ServletContextHandler servletContextHandler, Properties provProps) {
224         if (Boolean.parseBoolean(provProps.getProperty(
225             "org.onap.dmaap.datarouter.provserver.cadi.enabled", "false"))) {
226             try {
227                 servletContextHandler.addFilter(new FilterHolder(new DRProvCadiFilter(
228                     true, ProvRunner.getAafPropsUtils().getPropAccess())), "/*", EnumSet.of(DispatcherType.REQUEST));
229                 intlogger.info("PROV0001 AAF CADI filter enabled");
230             } catch (ServletException e) {
231                 intlogger.error("PROV0001 Failed to add CADI filter to server");
232             }
233
234         }
235     }
236 }