Replacing att.com namespace
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / Main.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 \r
24 \r
25 package org.onap.dmaap.datarouter.provisioning;\r
26 \r
27 import java.security.Security;\r
28 import java.util.Properties;\r
29 import java.util.Timer;\r
30 \r
31 import org.apache.log4j.Logger;\r
32 import org.eclipse.jetty.server.Connector;\r
33 import org.eclipse.jetty.server.Handler;\r
34 import org.eclipse.jetty.server.NCSARequestLog;\r
35 import org.eclipse.jetty.server.Server;\r
36 import org.eclipse.jetty.server.handler.ContextHandlerCollection;\r
37 import org.eclipse.jetty.server.handler.DefaultHandler;\r
38 import org.eclipse.jetty.server.handler.HandlerCollection;\r
39 import org.eclipse.jetty.server.handler.RequestLogHandler;\r
40 import org.eclipse.jetty.server.nio.SelectChannelConnector;\r
41 import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;\r
42 import org.eclipse.jetty.servlet.FilterHolder;\r
43 import org.eclipse.jetty.servlet.FilterMapping;\r
44 import org.eclipse.jetty.servlet.ServletContextHandler;\r
45 import org.eclipse.jetty.servlet.ServletHolder;\r
46 import org.eclipse.jetty.util.ssl.SslContextFactory;\r
47 import org.eclipse.jetty.util.thread.QueuedThreadPool;\r
48 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
49 import org.onap.dmaap.datarouter.provisioning.utils.LogfileLoader;\r
50 import org.onap.dmaap.datarouter.provisioning.utils.PurgeLogDirTask;\r
51 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;\r
52 \r
53 /**\r
54  * <p>\r
55  * A main class which may be used to start the provisioning server with an "embedded" Jetty server.\r
56  * Configuration is done via the properties file <i>provserver.properties</i>, which should be in the CLASSPATH.\r
57  * The provisioning server may also be packaged with a web.xml and started as a traditional webapp.\r
58  * </p>\r
59  * <p>\r
60  * Most of the work of the provisioning server is carried out within the eight servlets (configured below)\r
61  * that are used to handle each of the eight types of requests the server may receive.\r
62  * In addition, there are background threads started to perform other tasks:\r
63  * </p>\r
64  * <ul>\r
65  * <li>One background Thread runs the {@link LogfileLoader} in order to process incoming logfiles.\r
66  *   This Thread is created as a side effect of the first successful POST to the /internal/logs/ servlet.</li>\r
67  * <li>One background Thread runs the {@link SynchronizerTask} which is used to periodically\r
68  *   synchronize the database between active and standby servers.</li>\r
69  * <li>One background Thread runs the {@link Poker} which is used to notify the nodes whenever\r
70  *   provisioning data changes.</li>\r
71  * <li>One task is run once a day to run {@link PurgeLogDirTask} which purges older logs from the\r
72  *   /opt/app/datartr/logs directory.</li>\r
73  * </ul>\r
74  * <p>\r
75  * The provisioning server is stopped by issuing a GET to the URL http://127.0.0.1/internal/halt\r
76  * using <i>curl</i> or some other such tool.\r
77  * </p>\r
78  *\r
79  * @author Robert Eby\r
80  * @version $Id: Main.java,v 1.12 2014/03/12 19:45:41 eby Exp $\r
81  */\r
82 public class Main {\r
83         /** The truststore to use if none is specified */\r
84         public static final String DEFAULT_TRUSTSTORE           = "/opt/java/jdk/jdk180/jre/lib/security/cacerts";\r
85         public static final String KEYSTORE_TYPE_PROPERTY       = "org.onap.dmaap.datarouter.provserver.keystore.type";\r
86         public static final String KEYSTORE_PATH_PROPERTY       = "org.onap.dmaap.datarouter.provserver.keystore.path";\r
87         public static final String KEYSTORE_PASSWORD_PROPERTY   = "org.onap.dmaap.datarouter.provserver.keystore.password";\r
88         public static final String TRUSTSTORE_PATH_PROPERTY     = "org.onap.dmaap.datarouter.provserver.truststore.path";\r
89         public static final String TRUSTSTORE_PASSWORD_PROPERTY = "org.onap.dmaap.datarouter.provserver.truststore.password";\r
90 \r
91         /** The one and only {@link Server} instance in this JVM */\r
92         private static Server server;\r
93 \r
94         /**\r
95          * Starts the Data Router Provisioning server.\r
96          * @param args not used\r
97          * @throws Exception if Jetty has a problem starting\r
98          */\r
99         public static void main(String[] args) throws Exception {\r
100                 Security.setProperty("networkaddress.cache.ttl", "4");\r
101                 Logger logger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");\r
102 \r
103                 // Check DB is accessible and contains the expected tables\r
104                 if (! checkDatabase(logger))\r
105                         System.exit(1);\r
106 \r
107                 logger.info("PROV0000 **** AT&T Data Router Provisioning Server starting....");\r
108 \r
109                 // Get properties\r
110                 Properties p = (new DB()).getProperties();\r
111                 int http_port  = Integer.parseInt(p.getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080"));\r
112                 int https_port = Integer.parseInt(p.getProperty("org.onap.dmaap.datarouter.provserver.https.port", "8443"));\r
113 \r
114                 // HTTP connector\r
115                 SelectChannelConnector http = new SelectChannelConnector();\r
116                 http.setPort(http_port);\r
117                 http.setMaxIdleTime(300000);\r
118                 http.setRequestHeaderSize(2048);\r
119                 http.setAcceptors(2);\r
120                 http.setConfidentialPort(https_port);\r
121                 http.setLowResourcesConnections(20000);\r
122 \r
123                 // HTTPS connector\r
124                 SslSelectChannelConnector https = new SslSelectChannelConnector();\r
125                 https.setPort(https_port);\r
126                 https.setMaxIdleTime(30000);\r
127                 https.setRequestHeaderSize(8192);\r
128                 https.setAcceptors(2);\r
129 \r
130                 // SSL stuff\r
131                 SslContextFactory cf = https.getSslContextFactory();\r
132                 \r
133                 /**Skip SSLv3 Fixes*/\r
134                 cf.addExcludeProtocols("SSLv3");\r
135                 logger.info("Excluded protocols prov-"+cf.getExcludeProtocols());\r
136                 /**End of SSLv3 Fixes*/\r
137 \r
138                 cf.setKeyStoreType(p.getProperty(KEYSTORE_TYPE_PROPERTY, "jks"));\r
139                 cf.setKeyStorePath(p.getProperty(KEYSTORE_PATH_PROPERTY));\r
140                 cf.setKeyStorePassword(p.getProperty(KEYSTORE_PASSWORD_PROPERTY));\r
141                 cf.setKeyManagerPassword(p.getProperty("org.onap.dmaap.datarouter.provserver.keymanager.password"));\r
142                 String ts = p.getProperty(TRUSTSTORE_PATH_PROPERTY);\r
143                 if (ts != null && ts.length() > 0) {\r
144                         System.out.println("@@ TS -> "+ts);\r
145                         cf.setTrustStore(ts);\r
146                         cf.setTrustStorePassword(p.getProperty(TRUSTSTORE_PASSWORD_PROPERTY));\r
147                 } else {\r
148                         cf.setTrustStore(DEFAULT_TRUSTSTORE);\r
149                         cf.setTrustStorePassword("changeit");\r
150                 }\r
151                 cf.setTrustStore("/opt/app/datartr/self_signed/cacerts.jks");\r
152                 cf.setTrustStorePassword("changeit");\r
153                 cf.setWantClientAuth(true);\r
154 \r
155                 // Servlet and Filter configuration\r
156                 ServletContextHandler ctxt = new ServletContextHandler(0);\r
157                 ctxt.setContextPath("/");\r
158                 ctxt.addServlet(new ServletHolder(new FeedServlet()),         "/feed/*");\r
159                 ctxt.addServlet(new ServletHolder(new FeedLogServlet()),      "/feedlog/*");\r
160                 ctxt.addServlet(new ServletHolder(new PublishServlet()),      "/publish/*");\r
161                 ctxt.addServlet(new ServletHolder(new SubscribeServlet()),    "/subscribe/*");\r
162                 ctxt.addServlet(new ServletHolder(new StatisticsServlet()),       "/statistics/*");\r
163                 ctxt.addServlet(new ServletHolder(new SubLogServlet()),       "/sublog/*");\r
164                 ctxt.addServlet(new ServletHolder(new GroupServlet()),            "/group/*"); //Provision groups - Rally US708115 -1610 \r
165                 ctxt.addServlet(new ServletHolder(new SubscriptionServlet()), "/subs/*");\r
166                 ctxt.addServlet(new ServletHolder(new InternalServlet()),     "/internal/*");\r
167                 ctxt.addServlet(new ServletHolder(new RouteServlet()),        "/internal/route/*");\r
168                 ctxt.addServlet(new ServletHolder(new DRFeedsServlet()),      "/");\r
169                 ctxt.addFilter (new FilterHolder (new ThrottleFilter()),      "/publish/*", FilterMapping.REQUEST);\r
170 \r
171                 ContextHandlerCollection contexts = new ContextHandlerCollection();\r
172                 contexts.addHandler(ctxt);\r
173 \r
174                 // Request log configuration\r
175                 NCSARequestLog nrl = new NCSARequestLog();\r
176                 nrl.setFilename(p.getProperty("org.onap.dmaap.datarouter.provserver.accesslog.dir") + "/request.log.yyyy_mm_dd");\r
177                 nrl.setFilenameDateFormat("yyyyMMdd");\r
178                 nrl.setRetainDays(90);\r
179                 nrl.setAppend(true);\r
180                 nrl.setExtended(false);\r
181                 nrl.setLogCookies(false);\r
182                 nrl.setLogTimeZone("GMT");\r
183 \r
184                 RequestLogHandler reqlog = new RequestLogHandler();\r
185                 reqlog.setRequestLog(nrl);\r
186 \r
187                 // Server's Handler collection\r
188                 HandlerCollection hc = new HandlerCollection();\r
189                 hc.setHandlers(new Handler[] { contexts, new DefaultHandler() });\r
190                 hc.addHandler(reqlog);\r
191 \r
192                 // Server's thread pool\r
193                 QueuedThreadPool pool = new QueuedThreadPool();\r
194                 pool.setMinThreads(10);\r
195                 pool.setMaxThreads(200);\r
196                 pool.setDetailedDump(false);\r
197 \r
198                 // Daemon to clean up the log directory on a daily basis\r
199                 Timer rolex = new Timer();\r
200                 rolex.scheduleAtFixedRate(new PurgeLogDirTask(), 0, 86400000L); // run once per day\r
201 \r
202                 // Start LogfileLoader\r
203                 LogfileLoader.getLoader();\r
204 \r
205                 // The server itself\r
206                 server = new Server();\r
207                 server.setThreadPool(pool);\r
208                 server.setConnectors(new Connector[] { http, https });\r
209                 server.setHandler(hc);\r
210                 server.setStopAtShutdown(true);\r
211                 server.setSendServerVersion(true);\r
212                 server.setSendDateHeader(true);\r
213                 server.setGracefulShutdown(5000);       // allow 5 seconds for servlets to wrap up\r
214                 server.setDumpAfterStart(false);\r
215                 server.setDumpBeforeStop(false);\r
216 \r
217                 server.start();\r
218                 server.join();\r
219                 logger.info("PROV0001 **** AT&T Data Router Provisioning Server halted.");\r
220         }\r
221 \r
222         private static boolean checkDatabase(Logger logger) {\r
223                 DB db = new DB();\r
224                 return db.runRetroFits();\r
225         }\r
226 \r
227         /**\r
228          * Stop the Jetty server.\r
229          */\r
230         public static void shutdown() {\r
231                 new Thread() {\r
232                         @Override\r
233                         public void run() {\r
234                                 try {\r
235                                         server.stop();\r
236                                         Thread.sleep(5000L);\r
237                                         System.exit(0);\r
238                                 } catch (Exception e) {\r
239                                         // ignore\r
240                                 }\r
241                         }\r
242                 }.start();\r
243         }\r
244 }\r