1 /*******************************************************************************
2 * ============LICENSE_START==================================================
4 * * ===========================================================================
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * * ===========================================================================
7 * * Licensed under the Apache License, Version 2.0 (the "License");
8 * * you may not use this file except in compliance with the License.
9 * * You may obtain a copy of the License at
11 * * http://www.apache.org/licenses/LICENSE-2.0
13 * * Unless required by applicable law or agreed to in writing, software
14 * * distributed under the License is distributed on an "AS IS" BASIS,
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * * See the License for the specific language governing permissions and
17 * * limitations under the License.
18 * * ============LICENSE_END====================================================
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 ******************************************************************************/
25 package org.onap.dmaap.datarouter.provisioning;
27 import static java.lang.System.exit;
29 import com.att.eelf.configuration.EELFLogger;
30 import com.att.eelf.configuration.EELFManager;
32 import java.io.IOException;
33 import java.security.Security;
34 import java.util.EnumSet;
35 import java.util.Properties;
36 import java.util.Timer;
37 import javax.servlet.DispatcherType;
38 import org.eclipse.jetty.http.HttpVersion;
39 import org.eclipse.jetty.server.Connector;
40 import org.eclipse.jetty.server.Handler;
41 import org.eclipse.jetty.server.HttpConfiguration;
42 import org.eclipse.jetty.server.HttpConnectionFactory;
43 import org.eclipse.jetty.server.NCSARequestLog;
44 import org.eclipse.jetty.server.Server;
45 import org.eclipse.jetty.server.ServerConnector;
46 import org.eclipse.jetty.server.SslConnectionFactory;
47 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
48 import org.eclipse.jetty.server.handler.DefaultHandler;
49 import org.eclipse.jetty.server.handler.HandlerCollection;
50 import org.eclipse.jetty.server.handler.RequestLogHandler;
51 import org.eclipse.jetty.servlet.FilterHolder;
52 import org.eclipse.jetty.servlet.ServletContextHandler;
53 import org.eclipse.jetty.servlet.ServletHolder;
54 import org.eclipse.jetty.util.ssl.SslContextFactory;
55 import org.eclipse.jetty.util.thread.QueuedThreadPool;
56 import org.onap.dmaap.datarouter.provisioning.utils.AafPropsUtils;
57 import org.onap.dmaap.datarouter.provisioning.utils.DB;
58 import org.onap.dmaap.datarouter.provisioning.utils.DRProvCadiFilter;
59 import org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader;
60 import org.onap.dmaap.datarouter.provisioning.utils.PurgeLogDirTask;
61 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
65 * A main class which may be used to start the provisioning server with an "embedded" Jetty server. Configuration is
66 * done via the properties file <i>provserver.properties</i>, which should be in the CLASSPATH. The provisioning server
67 * may also be packaged with a web.xml and started as a traditional webapp.
70 * Most of the work of the provisioning server is carried out within the eight servlets (configured below) that are used
71 * to handle each of the eight types of requests the server may receive. In addition, there are background threads
72 * started to perform other tasks:
75 * <li>One background Thread runs the {@link LogfileLoader} in order to process incoming logfiles.
76 * This Thread is created as a side effect of the first successful POST to the /internal/logs/ servlet.</li>
77 * <li>One background Thread runs the {@link SynchronizerTask} which is used to periodically
78 * synchronize the database between active and standby servers.</li>
79 * <li>One background Thread runs the {@link Poker} which is used to notify the nodes whenever
80 * provisioning data changes.</li>
81 * <li>One task is run once a day to run {@link PurgeLogDirTask} which purges older logs from the
82 * /opt/app/datartr/logs directory.</li>
85 * The provisioning server is stopped by issuing a GET to the URL http://127.0.0.1/internal/halt using <i>curl</i> or
86 * some other such tool.
90 * @version $Id: Main.java,v 1.12 2014/03/12 19:45:41 eby Exp $
94 public static final EELFLogger intlogger = EELFManager.getInstance()
95 .getLogger("org.onap.dmaap.datarouter.provisioning.internal");
98 * The one and only {@link Server} instance in this JVM.
100 private static Server server;
101 static AafPropsUtils aafPropsUtils;
104 * Starts the Data Router Provisioning server.
106 * @param args not used
107 * @throws Exception if Jetty has a problem starting
109 public static void main(String[] args) throws Exception {
110 Security.setProperty("networkaddress.cache.ttl", "4");
111 // Check DB is accessible and contains the expected tables
112 if (!checkDatabase()) {
113 intlogger.error("Data Router Provisioning database init failure. Exiting.");
117 intlogger.info("PROV0000 **** Data Router Provisioning Server starting....");
119 Security.setProperty("networkaddress.cache.ttl", "4");
120 Properties provProperties = (new DB()).getProperties();
121 int httpPort = Integer.parseInt(provProperties
122 .getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080"));
123 final int httpsPort = Integer.parseInt(provProperties
124 .getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
126 // Server's thread pool
127 QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
128 queuedThreadPool.setMinThreads(10);
129 queuedThreadPool.setMaxThreads(200);
130 queuedThreadPool.setDetailedDump(false);
133 server = new Server(queuedThreadPool);
134 server.setStopAtShutdown(true);
135 server.setStopTimeout(5000);
136 server.setDumpAfterStart(false);
137 server.setDumpBeforeStop(false);
139 // Request log configuration
140 NCSARequestLog ncsaRequestLog = new NCSARequestLog();
141 ncsaRequestLog.setFilename(provProperties
142 .getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir")
143 + "/request.log.yyyy_mm_dd");
144 ncsaRequestLog.setFilenameDateFormat("yyyyMMdd");
145 ncsaRequestLog.setRetainDays(90);
146 ncsaRequestLog.setAppend(true);
147 ncsaRequestLog.setExtended(false);
148 ncsaRequestLog.setLogCookies(false);
149 ncsaRequestLog.setLogTimeZone("GMT");
151 RequestLogHandler requestLogHandler = new RequestLogHandler();
152 requestLogHandler.setRequestLog(ncsaRequestLog);
153 server.setRequestLog(ncsaRequestLog);
155 // HTTP configuration
156 HttpConfiguration httpConfiguration = new HttpConfiguration();
157 httpConfiguration.setSecureScheme("https");
158 httpConfiguration.setSecurePort(httpsPort);
159 httpConfiguration.setOutputBufferSize(32768);
160 httpConfiguration.setRequestHeaderSize(8192);
161 httpConfiguration.setResponseHeaderSize(8192);
162 httpConfiguration.setSendServerVersion(true);
163 httpConfiguration.setSendDateHeader(false);
166 AafPropsUtils.init(new File(provProperties.getProperty(
167 "org.onap.dmaap.datarouter.provserver.aafprops.path",
168 "/opt/app/osaaf/local/org.onap.dmaap-dr.props")));
169 } catch (IOException e) {
170 intlogger.error("NODE0314 Failed to load AAF props. Exiting", e);
173 aafPropsUtils = AafPropsUtils.getInstance();
176 HandlerCollection handlerCollection;
177 try (ServerConnector httpServerConnector =
178 new ServerConnector(server, new HttpConnectionFactory(httpConfiguration))) {
179 httpServerConnector.setPort(httpPort);
180 httpServerConnector.setAcceptQueueSize(2);
181 httpServerConnector.setIdleTimeout(300000);
184 SslContextFactory sslContextFactory = new SslContextFactory();
185 sslContextFactory.setKeyStoreType(AafPropsUtils.KEYSTORE_TYPE_PROPERTY);
186 sslContextFactory.setKeyStorePath(aafPropsUtils.getKeystorePathProperty());
187 sslContextFactory.setKeyStorePassword(aafPropsUtils.getKeystorePassProperty());
188 sslContextFactory.setKeyManagerPassword(aafPropsUtils.getKeystorePassProperty());
190 String truststorePathProperty = aafPropsUtils.getTruststorePathProperty();
191 if (truststorePathProperty != null && truststorePathProperty.length() > 0) {
192 intlogger.info("@@ TS -> " + truststorePathProperty);
193 sslContextFactory.setTrustStoreType(AafPropsUtils.TRUESTSTORE_TYPE_PROPERTY);
194 sslContextFactory.setTrustStorePath(truststorePathProperty);
195 sslContextFactory.setTrustStorePassword(aafPropsUtils.getTruststorePassProperty());
197 sslContextFactory.setTrustStorePath(AafPropsUtils.DEFAULT_TRUSTSTORE);
198 sslContextFactory.setTrustStorePassword("changeit");
201 sslContextFactory.setWantClientAuth(true);
202 sslContextFactory.setExcludeCipherSuites(
203 "SSL_RSA_WITH_DES_CBC_SHA",
204 "SSL_DHE_RSA_WITH_DES_CBC_SHA",
205 "SSL_DHE_DSS_WITH_DES_CBC_SHA",
206 "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
207 "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
208 "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
209 "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
211 sslContextFactory.addExcludeProtocols("SSLv3");
212 sslContextFactory.setIncludeProtocols(provProperties.getProperty(
213 "org.onap.dmaap.datarouter.provserver.https.include.protocols",
214 "TLSv1.1|TLSv1.2").trim().split("\\|"));
216 intlogger.info("Not supported protocols prov server:-"
217 + String.join(",", sslContextFactory.getExcludeProtocols()));
218 intlogger.info("Supported protocols prov server:-"
219 + String.join(",", sslContextFactory.getIncludeProtocols()));
220 intlogger.info("Not supported ciphers prov server:-"
221 + String.join(",", sslContextFactory.getExcludeCipherSuites()));
222 intlogger.info("Supported ciphers prov server:-"
223 + String.join(",", sslContextFactory.getIncludeCipherSuites()));
225 // HTTPS configuration
226 HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
227 httpsConfiguration.setRequestHeaderSize(8192);
230 try (ServerConnector httpsServerConnector = new ServerConnector(server,
231 new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
232 new HttpConnectionFactory(httpsConfiguration))) {
234 httpsServerConnector.setPort(httpsPort);
235 httpsServerConnector.setIdleTimeout(30000);
236 httpsServerConnector.setAcceptQueueSize(2);
238 // Servlet and Filter configuration
239 ServletContextHandler servletContextHandler = new ServletContextHandler(0);
240 servletContextHandler.setContextPath("/");
241 servletContextHandler.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
242 servletContextHandler.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
243 servletContextHandler.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
244 servletContextHandler.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
245 servletContextHandler.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
246 servletContextHandler.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
247 servletContextHandler.addServlet(new ServletHolder(new GroupServlet()), "/group/*");
248 servletContextHandler.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
249 servletContextHandler.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
250 servletContextHandler.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
251 servletContextHandler.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
252 servletContextHandler.addFilter(new FilterHolder(new ThrottleFilter()),
253 "/publish/*", EnumSet.of(DispatcherType.REQUEST));
255 //CADI Filter activation check
256 if (Boolean.parseBoolean(provProperties.getProperty(
257 "org.onap.dmaap.datarouter.provserver.cadi.enabled", "false"))) {
258 servletContextHandler.addFilter(new FilterHolder(new DRProvCadiFilter(true, aafPropsUtils.getPropAccess())),
259 "/*", EnumSet.of(DispatcherType.REQUEST));
260 intlogger.info("PROV0001 AAF CADI Auth enabled for ");
263 ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
264 contextHandlerCollection.addHandler(servletContextHandler);
266 // Server's Handler collection
267 handlerCollection = new HandlerCollection();
268 handlerCollection.setHandlers(new Handler[]{contextHandlerCollection, new DefaultHandler()});
269 handlerCollection.addHandler(requestLogHandler);
271 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
274 server.setHandler(handlerCollection);
276 // Daemon to clean up the log directory on a daily basis
277 Timer rolex = new Timer();
278 rolex.scheduleAtFixedRate(new PurgeLogDirTask(), 0, 86400000L); // run once per day
280 // Start LogfileLoader
281 LogfileLoader.getLoader();
285 intlogger.info("Prov Server started-" + server.getState());
286 } catch (Exception e) {
287 intlogger.error("Jetty failed to start. Exiting: " + e.getMessage(), e);
291 intlogger.info("PROV0001 **** AT&T Data Router Provisioning Server halted.");
294 private static boolean checkDatabase() {
296 return db.runRetroFits();
300 * Stop the Jetty server.
302 static void shutdown() {
308 } catch (Exception e) {
309 intlogger.error("Exception in Main.shutdown(): " + e.getMessage(), e);