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 org.apache.log4j.Logger;
28 import org.eclipse.jetty.http.HttpVersion;
29 import org.eclipse.jetty.server.*;
30 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
31 import org.eclipse.jetty.server.handler.DefaultHandler;
32 import org.eclipse.jetty.server.handler.HandlerCollection;
33 import org.eclipse.jetty.server.handler.RequestLogHandler;
34 import org.eclipse.jetty.servlet.FilterHolder;
35 import org.eclipse.jetty.servlet.ServletContextHandler;
36 import org.eclipse.jetty.servlet.ServletHolder;
37 import org.eclipse.jetty.util.ssl.SslContextFactory;
38 import org.eclipse.jetty.util.thread.QueuedThreadPool;
39 import org.onap.aaf.cadi.PropAccess;
40 import org.onap.dmaap.datarouter.provisioning.utils.*;
42 import javax.servlet.DispatcherType;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.security.Security;
46 import java.util.EnumSet;
47 import java.util.Properties;
48 import java.util.Timer;
52 * A main class which may be used to start the provisioning server with an "embedded" Jetty server. Configuration is
53 * done via the properties file <i>provserver.properties</i>, which should be in the CLASSPATH. The provisioning server
54 * may also be packaged with a web.xml and started as a traditional webapp.
57 * Most of the work of the provisioning server is carried out within the eight servlets (configured below) that are used
58 * to handle each of the eight types of requests the server may receive. In addition, there are background threads
59 * started to perform other tasks:
62 * <li>One background Thread runs the {@link LogfileLoader} in order to process incoming logfiles.
63 * This Thread is created as a side effect of the first successful POST to the /internal/logs/ servlet.</li>
64 * <li>One background Thread runs the {@link SynchronizerTask} which is used to periodically
65 * synchronize the database between active and standby servers.</li>
66 * <li>One background Thread runs the {@link Poker} which is used to notify the nodes whenever
67 * provisioning data changes.</li>
68 * <li>One task is run once a day to run {@link PurgeLogDirTask} which purges older logs from the
69 * /opt/app/datartr/logs directory.</li>
72 * The provisioning server is stopped by issuing a GET to the URL http://127.0.0.1/internal/halt using <i>curl</i> or
73 * some other such tool.
77 * @version $Id: Main.java,v 1.12 2014/03/12 19:45:41 eby Exp $
82 * The truststore to use if none is specified
84 static final String DEFAULT_TRUSTSTORE = "/opt/java/jdk/jdk180/jre/lib/security/cacerts";
85 static final String KEYSTORE_TYPE_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.type";
86 static final String KEYSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.path";
87 static final String KEYSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.keystore.password";
88 static final String TRUSTSTORE_PATH_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.path";
89 static final String TRUSTSTORE_PASS_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.password";
90 public static final Logger intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
93 * The one and only {@link Server} instance in this JVM
95 private static Server server;
98 InputStream getCadiProps() {
99 InputStream in = null;
101 in = getClass().getClassLoader().getResourceAsStream("drProvCadi.properties");
102 } catch (Exception e) {
103 intlogger.error("Exception in Main.getCadiProps() method ", e);
110 * Starts the Data Router Provisioning server.
112 * @param args not used
113 * @throws Exception if Jetty has a problem starting
115 public static void main(String[] args) throws Exception {
116 // Get prov properties
117 Properties provProperties = (new DB()).getProperties();
119 // Check DB is accessible and contains the expected tables
120 if (!checkDatabase()) {
124 intlogger.info("PROV0000 **** AT&T Data Router Provisioning Server starting....");
126 Security.setProperty("networkaddress.cache.ttl", "4");
127 int httpPort = Integer.parseInt(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080"));
128 int httpsPort = Integer.parseInt(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));
130 // Server's thread pool
131 QueuedThreadPool queuedThreadPool = new QueuedThreadPool();
132 queuedThreadPool.setMinThreads(10);
133 queuedThreadPool.setMaxThreads(200);
134 queuedThreadPool.setDetailedDump(false);
137 server = new Server(queuedThreadPool);
138 server.setStopAtShutdown(true);
139 server.setStopTimeout(5000);
140 server.setDumpAfterStart(false);
141 server.setDumpBeforeStop(false);
143 // Request log configuration
144 NCSARequestLog ncsaRequestLog = new NCSARequestLog();
145 ncsaRequestLog.setFilename(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");
146 ncsaRequestLog.setFilenameDateFormat("yyyyMMdd");
147 ncsaRequestLog.setRetainDays(90);
148 ncsaRequestLog.setAppend(true);
149 ncsaRequestLog.setExtended(false);
150 ncsaRequestLog.setLogCookies(false);
151 ncsaRequestLog.setLogTimeZone("GMT");
153 RequestLogHandler requestLogHandler = new RequestLogHandler();
154 requestLogHandler.setRequestLog(ncsaRequestLog);
155 server.setRequestLog(ncsaRequestLog);
157 // HTTP configuration
158 HttpConfiguration httpConfiguration = new HttpConfiguration();
159 httpConfiguration.setSecureScheme("https");
160 httpConfiguration.setSecurePort(httpsPort);
161 httpConfiguration.setOutputBufferSize(32768);
162 httpConfiguration.setRequestHeaderSize(8192);
163 httpConfiguration.setResponseHeaderSize(8192);
164 httpConfiguration.setSendServerVersion(true);
165 httpConfiguration.setSendDateHeader(false);
168 HandlerCollection handlerCollection;
169 try (ServerConnector httpServerConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration))) {
170 httpServerConnector.setPort(httpPort);
171 httpServerConnector.setAcceptQueueSize(2);
172 httpServerConnector.setIdleTimeout(300000);
175 SslContextFactory sslContextFactory = new SslContextFactory();
176 sslContextFactory.setKeyStoreType(provProperties.getProperty(KEYSTORE_TYPE_PROPERTY, "jks"));
177 sslContextFactory.setKeyStorePath(provProperties.getProperty(KEYSTORE_PATH_PROPERTY));
178 sslContextFactory.setKeyStorePassword(provProperties.getProperty(KEYSTORE_PASS_PROPERTY));
179 sslContextFactory.setKeyManagerPassword(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.keymanager.password"));
181 String ts = provProperties.getProperty(TRUSTSTORE_PATH_PROPERTY);
182 if (ts != null && ts.length() > 0) {
183 intlogger.info("@@ TS -> " + ts);
184 sslContextFactory.setTrustStorePath(ts);
185 sslContextFactory.setTrustStorePassword(provProperties.getProperty(TRUSTSTORE_PASS_PROPERTY));
187 sslContextFactory.setTrustStorePath(DEFAULT_TRUSTSTORE);
188 sslContextFactory.setTrustStorePassword("changeit");
191 sslContextFactory.setWantClientAuth(true);
192 sslContextFactory.setExcludeCipherSuites(
193 "SSL_RSA_WITH_DES_CBC_SHA",
194 "SSL_DHE_RSA_WITH_DES_CBC_SHA",
195 "SSL_DHE_DSS_WITH_DES_CBC_SHA",
196 "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
197 "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
198 "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
199 "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
201 sslContextFactory.addExcludeProtocols("SSLv3");
202 sslContextFactory.setIncludeProtocols(provProperties.getProperty(
203 "org.onap.dmaap.datarouter.provserver.https.include.protocols", "TLSv1.1|TLSv1.2").trim().split("\\|"));
205 intlogger.info("Not supported protocols prov server:-" + String.join(",", sslContextFactory.getExcludeProtocols()));
206 intlogger.info("Supported protocols prov server:-" + String.join(",", sslContextFactory.getIncludeProtocols()));
207 intlogger.info("Not supported ciphers prov server:-" + String.join(",", sslContextFactory.getExcludeCipherSuites()));
208 intlogger.info("Supported ciphers prov server:-" + String.join(",", sslContextFactory.getIncludeCipherSuites()));
210 // HTTPS configuration
211 HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
212 httpsConfiguration.setRequestHeaderSize(8192);
215 try (ServerConnector httpsServerConnector = new ServerConnector(server,
216 new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
217 new HttpConnectionFactory(httpsConfiguration))) {
219 httpsServerConnector.setPort(httpsPort);
220 httpsServerConnector.setIdleTimeout(30000);
221 httpsServerConnector.setAcceptQueueSize(2);
223 // Servlet and Filter configuration
224 ServletContextHandler servletContextHandler = new ServletContextHandler(0);
225 servletContextHandler.setContextPath("/");
226 servletContextHandler.addServlet(new ServletHolder(new FeedServlet()), "/feed/*");
227 servletContextHandler.addServlet(new ServletHolder(new FeedLogServlet()), "/feedlog/*");
228 servletContextHandler.addServlet(new ServletHolder(new PublishServlet()), "/publish/*");
229 servletContextHandler.addServlet(new ServletHolder(new SubscribeServlet()), "/subscribe/*");
230 servletContextHandler.addServlet(new ServletHolder(new StatisticsServlet()), "/statistics/*");
231 servletContextHandler.addServlet(new ServletHolder(new SubLogServlet()), "/sublog/*");
232 servletContextHandler.addServlet(new ServletHolder(new GroupServlet()), "/group/*");
233 servletContextHandler.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");
234 servletContextHandler.addServlet(new ServletHolder(new InternalServlet()), "/internal/*");
235 servletContextHandler.addServlet(new ServletHolder(new RouteServlet()), "/internal/route/*");
236 servletContextHandler.addServlet(new ServletHolder(new DRFeedsServlet()), "/");
237 servletContextHandler.addFilter(new FilterHolder(new ThrottleFilter()), "/publish/*", EnumSet.of(DispatcherType.REQUEST));
239 //CADI Filter activation check
240 if (Boolean.parseBoolean(provProperties.getProperty("org.onap.dmaap.datarouter.provserver.cadi.enabled", "false"))) {
241 //Get cadi properties
242 Properties cadiProperties = null;
244 intlogger.info("PROV0001 Prov - Loading CADI properties");
245 cadiProperties = new Properties();
246 Inner obj = new Main().new Inner();
247 InputStream in = obj.getCadiProps();
248 cadiProperties.load(in);
249 } catch (IOException e1) {
250 intlogger.error("PROV0001 Exception loading CADI properties", e1);
252 cadiProperties.setProperty("aaf_locate_url", provProperties.getProperty("org.onap.dmaap.datarouter.provserver.cadi.aaf.url", "https://aaf-onap-test.osaaf.org:8095"));
253 intlogger.info("PROV0001 aaf_url set to - " + cadiProperties.getProperty("aaf_url"));
255 PropAccess access = new PropAccess(cadiProperties);
256 servletContextHandler.addFilter(new FilterHolder(new DRProvCadiFilter(true, access)), "/*", EnumSet.of(DispatcherType.REQUEST));
259 ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
260 contextHandlerCollection.addHandler(servletContextHandler);
262 // Server's Handler collection
263 handlerCollection = new HandlerCollection();
264 handlerCollection.setHandlers(new Handler[]{contextHandlerCollection, new DefaultHandler()});
265 handlerCollection.addHandler(requestLogHandler);
267 server.setConnectors(new Connector[]{httpServerConnector, httpsServerConnector});
270 server.setHandler(handlerCollection);
272 // Daemon to clean up the log directory on a daily basis
273 Timer rolex = new Timer();
274 rolex.scheduleAtFixedRate(new PurgeLogDirTask(), 0, 86400000L); // run once per day
276 // Start LogfileLoader
277 LogfileLoader.getLoader();
281 intlogger.info("Prov Server started-" + server.getState());
282 } catch (Exception e) {
283 intlogger.info("Jetty failed to start. Reporting will we unavailable", e);
286 intlogger.info("PROV0001 **** AT&T Data Router Provisioning Server halted.");
289 private static boolean checkDatabase() {
291 return db.runRetroFits();
295 * Stop the Jetty server.
297 static void shutdown() {
303 } catch (Exception e) {
304 intlogger.error("Exception in Main.shutdown() method " + e);