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