Update project structure to org.onap
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / BaseServlet.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 static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;\r
28 \r
29 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;\r
30 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;\r
31 \r
32 import java.io.IOException;\r
33 import java.io.InputStream;\r
34 import java.net.InetAddress;\r
35 import java.net.UnknownHostException;\r
36 import java.security.cert.X509Certificate;\r
37 import java.sql.Connection;\r
38 import java.sql.SQLException;\r
39 import java.util.HashMap;\r
40 import java.util.HashSet;\r
41 import java.util.Map;\r
42 import java.util.Set;\r
43 import java.util.List;\r
44 import java.util.ArrayList;\r
45 \r
46 import javax.servlet.ServletConfig;\r
47 import javax.servlet.ServletException;\r
48 import javax.servlet.http.HttpServlet;\r
49 import javax.servlet.http.HttpServletRequest;\r
50 \r
51 import org.apache.log4j.Logger;\r
52 import org.json.JSONObject;\r
53 import org.json.JSONTokener;\r
54 import org.onap.dmaap.datarouter.authz.Authorizer;\r
55 import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;\r
56 import org.onap.dmaap.datarouter.authz.impl.ProvDataProvider;\r
57 import org.onap.dmaap.datarouter.provisioning.beans.Deleteable;\r
58 import org.onap.dmaap.datarouter.provisioning.beans.Feed;\r
59 import org.onap.dmaap.datarouter.provisioning.beans.Group;\r
60 import org.onap.dmaap.datarouter.provisioning.beans.Insertable;\r
61 import org.onap.dmaap.datarouter.provisioning.beans.NodeClass;\r
62 import org.onap.dmaap.datarouter.provisioning.beans.Parameters;\r
63 import org.onap.dmaap.datarouter.provisioning.beans.Subscription;\r
64 import org.onap.dmaap.datarouter.provisioning.beans.Updateable;\r
65 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
66 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;\r
67 import org.json.JSONException;  \r
68 import org.slf4j.MDC;\r
69 \r
70 import java.util.Properties;\r
71 import java.util.regex.Pattern;\r
72 import javax.mail.Message;\r
73 import javax.mail.MessagingException;\r
74 import javax.mail.Multipart;\r
75 import javax.mail.Session;\r
76 import javax.mail.Transport;\r
77 import javax.mail.internet.AddressException;\r
78 import javax.mail.internet.InternetAddress;\r
79 import javax.mail.internet.MimeBodyPart;\r
80 import javax.mail.internet.MimeMessage;\r
81 import javax.mail.internet.MimeMultipart;\r
82 /**\r
83  * This is the base class for all Servlets in the provisioning code.\r
84  * It provides standard constants and some common methods.\r
85  *\r
86  * @author Robert Eby\r
87  * @version $Id: BaseServlet.java,v 1.16 2014/03/12 19:45:40 eby Exp $\r
88  */\r
89 @SuppressWarnings("serial")\r
90 public class BaseServlet extends HttpServlet implements ProvDataProvider {\r
91         public static final String BEHALF_HEADER         = "X-ATT-DR-ON-BEHALF-OF";\r
92         public static final String FEED_BASECONTENT_TYPE = "application/vnd.att-dr.feed";\r
93         public static final String FEED_CONTENT_TYPE     = "application/vnd.att-dr.feed; version=2.0";\r
94         public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.att-dr.feed-full; version=2.0";\r
95         public static final String FEEDLIST_CONTENT_TYPE = "application/vnd.att-dr.feed-list; version=1.0";\r
96         public static final String SUB_BASECONTENT_TYPE  = "application/vnd.att-dr.subscription";\r
97         public static final String SUB_CONTENT_TYPE      = "application/vnd.att-dr.subscription; version=2.0";\r
98         public static final String SUBFULL_CONTENT_TYPE  = "application/vnd.att-dr.subscription-full; version=2.0";\r
99         public static final String SUBLIST_CONTENT_TYPE  = "application/vnd.att-dr.subscription-list; version=1.0";\r
100 \r
101         \r
102         //Adding groups functionality, ...1610\r
103         public static final String GROUP_BASECONTENT_TYPE = "application/vnd.att-dr.group";\r
104         public static final String GROUP_CONTENT_TYPE     = "application/vnd.att-dr.group; version=2.0";\r
105         public static final String GROUPFULL_CONTENT_TYPE = "application/vnd.att-dr.group-full; version=2.0";\r
106         public static final String GROUPLIST_CONTENT_TYPE = "application/vnd.att-dr.fegrouped-list; version=1.0";\r
107 \r
108 \r
109         public static final String LOGLIST_CONTENT_TYPE  = "application/vnd.att-dr.log-list; version=1.0";\r
110         public static final String PROVFULL_CONTENT_TYPE1 = "application/vnd.att-dr.provfeed-full; version=1.0";\r
111         public static final String PROVFULL_CONTENT_TYPE2 = "application/vnd.att-dr.provfeed-full; version=2.0";\r
112         public static final String CERT_ATTRIBUTE        = "javax.servlet.request.X509Certificate";\r
113 \r
114         public static final String DB_PROBLEM_MSG = "There has been a problem with the DB.  It is suggested you try the operation again.";\r
115 \r
116         public static final int    DEFAULT_MAX_FEEDS     = 10000;\r
117         public static final int    DEFAULT_MAX_SUBS      = 100000;\r
118         public static final int    DEFAULT_POKETIMER1    = 5;\r
119         public static final int    DEFAULT_POKETIMER2    = 30;\r
120         public static final String DEFAULT_DOMAIN        = "web.att.com";\r
121         public static final String DEFAULT_PROVSRVR_NAME = "feeds-drtr.web.att.com";\r
122         public static final String RESEARCH_SUBNET       = "135.207.136.128/25";\r
123         public static final String STATIC_ROUTING_NODES       = ""; //Adding new param for static Routing - Rally:US664862-1610\r
124 \r
125         /** A boolean to trigger one time "provisioning changed" event on startup */\r
126         private static boolean startmsg_flag  = true;\r
127         /** This POD should require SSL connections from clients; pulled from the DB (PROV_REQUIRE_SECURE) */\r
128         private static boolean require_secure = true;\r
129         /** This POD should require signed, recognized certificates from clients; pulled from the DB (PROV_REQUIRE_CERT) */\r
130         private static boolean require_cert   = true;\r
131         /** The set of authorized addresses and networks; pulled from the DB (PROV_AUTH_ADDRESSES) */\r
132         private static Set<String> authorizedAddressesAndNetworks = new HashSet<String>();\r
133         /** The set of authorized names; pulled from the DB (PROV_AUTH_SUBJECTS) */\r
134         private static Set<String> authorizedNames = new HashSet<String>();\r
135         /** The FQDN of the initially "active" provisioning server in this Data Router ecosystem */\r
136         private static String initial_active_pod;\r
137         /** The FQDN of the initially "standby" provisioning server in this Data Router ecosystem */\r
138         private static String initial_standby_pod;\r
139         /** The FQDN of this provisioning server in this Data Router ecosystem */\r
140         private static String this_pod;\r
141         /** "Timer 1" - used to determine when to notify nodes of provisioning changes */\r
142         private static long poke_timer1;\r
143         /** "Timer 2" - used to determine when to notify nodes of provisioning changes */\r
144         private static long poke_timer2;\r
145         /** Array of nodes names and/or FQDNs */\r
146         private static String[] nodes = new String[0];\r
147         /** Array of node IP addresses */\r
148         private static InetAddress[] nodeAddresses = new InetAddress[0];\r
149         /** Array of POD IP addresses */\r
150         private static InetAddress[] podAddresses = new InetAddress[0];\r
151         /** The maximum number of feeds allowed; pulled from the DB (PROV_MAXFEED_COUNT) */\r
152         protected static int max_feeds    = 0;\r
153         /** The maximum number of subscriptions allowed; pulled from the DB (PROV_MAXSUB_COUNT) */\r
154         protected static int max_subs     = 0;\r
155         /** The current number of feeds in the system */\r
156         protected static int active_feeds = 0;\r
157         /** The current number of subscriptions in the system */\r
158         protected static int active_subs  = 0;\r
159         /** The domain used to generate a FQDN from the "bare" node names */\r
160         public static String prov_domain = "web.att.com";\r
161         /** The standard FQDN of the provisioning server in this Data Router ecosystem */\r
162         public static String prov_name   = "feeds-drtr.web.att.com";\r
163         /** The standard FQDN of the ACTIVE provisioning server in this Data Router ecosystem */\r
164         public static String active_prov_name   = "feeds-drtr.web.att.com";\r
165         /** Special subnet that is allowed access to /internal */\r
166         protected static String special_subnet = RESEARCH_SUBNET;\r
167 \r
168         /** Special subnet that is allowed access to /internal to Lab Machine */\r
169         protected static String special_subnet_secondary = RESEARCH_SUBNET;\r
170         protected static String static_routing_nodes = STATIC_ROUTING_NODES; //Adding new param for static Routing - Rally:US664862-1610\r
171 \r
172         /** This logger is used to log provisioning events */\r
173         protected static Logger eventlogger;\r
174         /** This logger is used to log internal events (errors, etc.) */\r
175         protected static Logger intlogger;\r
176         /** Authorizer - interface to the Policy Engine */\r
177         protected static Authorizer authz;\r
178         /** The Synchronizer used to sync active DB to standby one */\r
179         protected static SynchronizerTask synctask = null;\r
180     \r
181         //Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
182         private InetAddress thishost;\r
183         private InetAddress loopback;\r
184     private static Boolean mailSendFlag = false;\r
185 \r
186         public static final String MAILCONFIG_FILE = "mail.properties";\r
187         private static Properties mailprops;\r
188         /**\r
189          * Initialize data common to all the provisioning server servlets.\r
190          */\r
191         protected BaseServlet() {\r
192                 if (eventlogger == null)\r
193                         eventlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.events");\r
194                 if (intlogger == null)\r
195                         intlogger   = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");\r
196                 if (authz == null)\r
197                         authz = new ProvAuthorizer(this);\r
198                 if (startmsg_flag) {\r
199                         startmsg_flag = false;\r
200                         provisioningParametersChanged();\r
201                 }\r
202                 if (synctask == null) {\r
203                         synctask = SynchronizerTask.getSynchronizer();\r
204                 }\r
205                 String name = this.getClass().getName();\r
206                 intlogger.info("PROV0002 Servlet "+name+" started.");\r
207         }\r
208         @Override\r
209         public void init(ServletConfig config) throws ServletException {\r
210                 super.init(config);\r
211                 try {\r
212                         thishost = InetAddress.getLocalHost();\r
213                         loopback = InetAddress.getLoopbackAddress();\r
214                         checkHttpsRelaxation(); //Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
215                 } catch (UnknownHostException e) {\r
216                         // ignore\r
217                 }\r
218         }\r
219         protected int getIdFromPath(HttpServletRequest req) {\r
220                 String path = req.getPathInfo();\r
221                 if (path == null || path.length() < 2)\r
222                         return -1;\r
223                 try {\r
224                         return Integer.parseInt(path.substring(1));\r
225                 } catch (NumberFormatException e) {\r
226                         return -1;\r
227                 }\r
228         }\r
229         /**\r
230          * Read the request's input stream and return a JSONObject from it\r
231          * @param req the HTTP request\r
232          * @return the JSONObject, or null if the stream cannot be parsed\r
233          */\r
234         protected JSONObject getJSONfromInput(HttpServletRequest req) {\r
235                 JSONObject jo = null;\r
236                 try {\r
237                         jo = new JSONObject(new JSONTokener(req.getInputStream()));\r
238                         if (intlogger.isDebugEnabled())\r
239                                 intlogger.debug("JSON: "+jo.toString());\r
240                 } catch (Exception e) {\r
241                         intlogger.info("Error reading JSON: "+e);\r
242                 }\r
243                 return jo;\r
244         }\r
245         /**\r
246          * Check if the remote host is authorized to perform provisioning.\r
247          * Is the request secure?\r
248          * Is it coming from an authorized IP address or network (configured via PROV_AUTH_ADDRESSES)?\r
249          * Does it have a valid client certificate (configured via PROV_AUTH_SUBJECTS)?\r
250          * @param request the request\r
251          * @return an error string, or null if all is OK\r
252          */\r
253         protected String isAuthorizedForProvisioning(HttpServletRequest request) {\r
254                 // Is the request https?\r
255                 if (require_secure && !request.isSecure()) {\r
256                         return "Request must be made over an HTTPS connection.";\r
257                 }\r
258 \r
259                 // Is remote IP authorized?\r
260                 String remote = request.getRemoteAddr();\r
261                 try {\r
262                         boolean found = false;\r
263                         InetAddress ip = InetAddress.getByName(remote);\r
264                         for (String addrnet : authorizedAddressesAndNetworks) {\r
265                                 found |= addressMatchesNetwork(ip, addrnet);\r
266                         }\r
267                         if (!found) {\r
268                                 return "Unauthorized address: "+remote;\r
269                         }\r
270                 } catch (UnknownHostException e) {\r
271                         return "Unauthorized address: "+remote;\r
272                 }\r
273 \r
274                 // Does remote have a valid certificate?\r
275                 if (require_cert) {\r
276                         X509Certificate certs[] = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);\r
277                         if (certs == null || certs.length == 0) {\r
278                                 return "Client certificate is missing.";\r
279                         }\r
280                         // cert[0] is the client cert\r
281                         // see http://www.proto.research.att.com/java/java7/api/javax/net/ssl/SSLSession.html#getPeerCertificates()\r
282                         String name = certs[0].getSubjectX500Principal().getName();\r
283                         if (!authorizedNames.contains(name)) {\r
284                                 return "No authorized certificate found.";\r
285                         }\r
286                 }\r
287 \r
288                 // No problems!\r
289                 return null;\r
290         }\r
291         /**\r
292          * Check if the remote IP address is authorized to see the /internal URL tree.\r
293          * @param request the HTTP request\r
294          * @return true iff authorized\r
295          */\r
296         protected boolean isAuthorizedForInternal(HttpServletRequest request) {\r
297                 try {\r
298                         InetAddress ip = InetAddress.getByName(request.getRemoteAddr());\r
299                         for (InetAddress node : getNodeAddresses()) {\r
300                                 if (node != null && ip.equals(node))\r
301                                         return true;\r
302                         }\r
303                         for (InetAddress pod : getPodAddresses()) {\r
304                                 if (pod != null && ip.equals(pod))\r
305                                         return true;\r
306                         }\r
307                         if (thishost != null && ip.equals(thishost))\r
308                                 return true;\r
309                         if (loopback != null && ip.equals(loopback))\r
310                                 return true;\r
311                         // Also allow the "special subnet" access\r
312                         if (addressMatchesNetwork(ip, special_subnet_secondary))\r
313                                 return true;\r
314                         if (addressMatchesNetwork(ip, special_subnet))\r
315                                 return true;\r
316                 } catch (UnknownHostException e) {\r
317                         // ignore\r
318                 }\r
319                 return false;\r
320         }\r
321         /**\r
322          * Check if an IP address matches a network address.\r
323          * @param ip the IP address\r
324          * @param s the network address; a bare IP address may be matched also\r
325          * @return true if they intersect\r
326          */\r
327         protected static boolean addressMatchesNetwork(InetAddress ip, String s) {\r
328                 int mlen = -1;\r
329                 int n = s.indexOf("/");\r
330                 if (n >= 0) {\r
331                         mlen = Integer.parseInt(s.substring(n+1));\r
332                         s = s.substring(0, n);\r
333                 }\r
334                 try {\r
335                         InetAddress i2 = InetAddress.getByName(s);\r
336                         byte[] b1 = ip.getAddress();\r
337                         byte[] b2 = i2.getAddress();\r
338                         if (b1.length != b2.length)\r
339                                 return false;\r
340                         if (mlen > 0) {\r
341                                 byte[] masks = {\r
342                                         (byte)0x00, (byte)0x80, (byte)0xC0, (byte)0xE0,\r
343                                         (byte)0xF0, (byte)0xF8, (byte)0xFC, (byte)0xFE\r
344                                 };\r
345                                 byte mask = masks[mlen%8];\r
346                                 for (n = mlen/8; n < b1.length; n++) {\r
347                                         b1[n] &= mask;\r
348                                         b2[n] &= mask;\r
349                                         mask = 0;\r
350                                 }\r
351                         }\r
352                         for (n = 0; n < b1.length; n++)\r
353                                 if (b1[n] != b2[n])\r
354                                         return false;\r
355                 } catch (UnknownHostException e) {\r
356                         return false;\r
357                 }\r
358                 return true;\r
359         }\r
360         /**\r
361          * Something has changed in the provisioning data.\r
362          * Start the timers that will cause the pre-packaged JSON string to be regenerated,\r
363          * and cause nodes and the other provisioning server to be notified.\r
364          */\r
365         public static void provisioningDataChanged() {\r
366                 long now = System.currentTimeMillis();\r
367                 Poker p = Poker.getPoker();\r
368                 p.setTimers(now + (poke_timer1 * 1000L), now + (poke_timer2 * 1000L));\r
369         }\r
370         /**\r
371          * Something in the parameters has changed, reload all parameters from the DB.\r
372          */\r
373         public static void provisioningParametersChanged() {\r
374                 Map<String,String> map         = Parameters.getParameters();\r
375                 require_secure   = getBoolean(map, Parameters.PROV_REQUIRE_SECURE);\r
376                 require_cert     = getBoolean(map, Parameters.PROV_REQUIRE_CERT);\r
377                 authorizedAddressesAndNetworks = getSet(map, Parameters.PROV_AUTH_ADDRESSES);\r
378                 authorizedNames  = getSet    (map, Parameters.PROV_AUTH_SUBJECTS);\r
379                 nodes            = getSet    (map, Parameters.NODES).toArray(new String[0]);\r
380                 max_feeds        = getInt    (map, Parameters.PROV_MAXFEED_COUNT, DEFAULT_MAX_FEEDS);\r
381                 max_subs         = getInt    (map, Parameters.PROV_MAXSUB_COUNT, DEFAULT_MAX_SUBS);\r
382                 poke_timer1      = getInt    (map, Parameters.PROV_POKETIMER1, DEFAULT_POKETIMER1);\r
383                 poke_timer2      = getInt    (map, Parameters.PROV_POKETIMER2, DEFAULT_POKETIMER2);\r
384                 prov_domain      = getString (map, Parameters.PROV_DOMAIN, DEFAULT_DOMAIN);\r
385                 prov_name        = getString (map, Parameters.PROV_NAME, DEFAULT_PROVSRVR_NAME);\r
386                 active_prov_name = getString (map, Parameters.PROV_ACTIVE_NAME, prov_name);\r
387                 special_subnet   = getString (map, Parameters.PROV_SPECIAL_SUBNET, RESEARCH_SUBNET);\r
388                 static_routing_nodes = getString (map, Parameters.STATIC_ROUTING_NODES, ""); //Adding new param for static Routing - Rally:US664862-1610\r
389                 initial_active_pod  = getString (map, Parameters.ACTIVE_POD, "");\r
390                 initial_standby_pod = getString (map, Parameters.STANDBY_POD, "");\r
391                 static_routing_nodes = getString (map, Parameters.STATIC_ROUTING_NODES, ""); //Adding new param for static Routing - Rally:US664862-1610\r
392                 active_feeds     = Feed.countActiveFeeds();\r
393                 active_subs      = Subscription.countActiveSubscriptions();\r
394                 try {\r
395                         this_pod = InetAddress.getLocalHost().getHostName();\r
396                 } catch (UnknownHostException e) {\r
397                         this_pod = "";\r
398                         intlogger.warn("PROV0014 Cannot determine the name of this provisioning server.");\r
399                 }\r
400 \r
401                 // Normalize the nodes, and fill in nodeAddresses\r
402                 InetAddress[] na = new InetAddress[nodes.length];\r
403                 for (int i = 0; i < nodes.length; i++) {\r
404                         if (nodes[i].indexOf('.') < 0)\r
405                                 nodes[i] += "." + prov_domain;\r
406                         try {\r
407                                 na[i] = InetAddress.getByName(nodes[i]);\r
408                                 intlogger.debug("PROV0003 DNS lookup: "+nodes[i]+" => "+na[i].toString());\r
409                         } catch (UnknownHostException e) {\r
410                                 na[i] = null;\r
411                                 intlogger.warn("PROV0004 Cannot lookup "+nodes[i]+": "+e);\r
412                         }\r
413                 }\r
414 \r
415                 //Reset Nodes arr after - removing static routing Nodes, Rally Userstory - US664862 .   \r
416                 List<String> filterNodes = new ArrayList<>();           \r
417                 for (int i = 0; i < nodes.length; i++) {                \r
418                         if(!static_routing_nodes.contains(nodes[i])){           \r
419                                 filterNodes.add(nodes[i]);              \r
420                         }               \r
421                 }               \r
422                 String [] filteredNodes = filterNodes.toArray(new String[filterNodes.size()]);                          \r
423                 nodes = filteredNodes;\r
424 \r
425                 nodeAddresses = na;\r
426                 NodeClass.setNodes(nodes);              // update NODES table\r
427 \r
428                 // Normalize the PODs, and fill in podAddresses\r
429                 String[] pods = getPods();\r
430                 na = new InetAddress[pods.length];\r
431                 for (int i = 0; i < pods.length; i++) {\r
432                         if (pods[i].indexOf('.') < 0)\r
433                                 pods[i] += "." + prov_domain;\r
434                         try {\r
435                                 na[i] = InetAddress.getByName(pods[i]);\r
436                                 intlogger.debug("PROV0003 DNS lookup: "+pods[i]+" => "+na[i].toString());\r
437                         } catch (UnknownHostException e) {\r
438                                 na[i] = null;\r
439                                 intlogger.warn("PROV0004 Cannot lookup "+pods[i]+": "+e);\r
440                         }\r
441                 }\r
442                 podAddresses = na;\r
443 \r
444                 // Update ThrottleFilter\r
445                 ThrottleFilter.configure();\r
446 \r
447                 // Check if we are active or standby POD\r
448                 if (!isInitialActivePOD() && !isInitialStandbyPOD())\r
449                         intlogger.warn("PROV0015 This machine is neither the active nor the standby POD.");\r
450         }\r
451 \r
452 \r
453         /**Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
454          * Load mail properties.\r
455          * @author vs215k\r
456          *  \r
457         **/\r
458         private void loadMailProperties() {\r
459                 if (mailprops == null) {\r
460                         mailprops = new Properties();\r
461                         InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE);\r
462                         try {\r
463                                 mailprops.load(inStream);\r
464                         } catch (IOException e) {\r
465                                 intlogger.fatal("PROV9003 Opening properties: "+e.getMessage());\r
466                                 e.printStackTrace();\r
467                                 System.exit(1);\r
468                         }\r
469                         finally {\r
470                                 try {\r
471                                         inStream.close();\r
472                                 } \r
473                                 catch (IOException e) {\r
474                                 }\r
475                         }\r
476                 }\r
477         }\r
478         \r
479         /**Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
480          * Check if HTTPS Relexaction is enabled \r
481          * @author vs215k\r
482          *  \r
483         **/\r
484         private void checkHttpsRelaxation() {\r
485                 if(mailSendFlag == false) {\r
486                         Properties p = (new DB()).getProperties();\r
487                         intlogger.info("HTTPS relaxatio: "+p.get("com.att.research.datarouter.provserver.https.relaxation"));\r
488                         \r
489                         if(p.get("com.att.research.datarouter.provserver.https.relaxation").equals("true")) {\r
490                             try {\r
491                                   notifyPSTeam(p.get("com.att.research.datarouter.provserver.https.relax.notify").toString());\r
492                             } \r
493                                 catch (Exception e) {\r
494                                     e.printStackTrace();\r
495                             }\r
496                          }\r
497                         mailSendFlag = true;\r
498                 }\r
499         }\r
500         \r
501         /**Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.\r
502          * @author vs215k\r
503          * @param email - list of email ids to notify if HTTP relexcation is enabled. \r
504         **/\r
505         private void notifyPSTeam(String email) throws Exception {\r
506                 loadMailProperties(); //Load HTTPS Relex mail properties.\r
507                 String[] emails = email.split(Pattern.quote("|"));\r
508         \r
509         Properties mailproperties = new Properties();\r
510                 mailproperties.put("mail.smtp.host", mailprops.get("com.att.dmaap.datarouter.mail.server"));\r
511                 mailproperties.put("mail.transport.protocol", mailprops.get("com.att.dmaap.datarouter.mail.protocol"));\r
512                 \r
513         Session session = Session.getDefaultInstance(mailproperties, null);\r
514         Multipart mp = new MimeMultipart();\r
515         MimeBodyPart htmlPart = new MimeBodyPart();\r
516         \r
517         try {\r
518                 \r
519           Message msg = new MimeMessage(session);\r
520           msg.setFrom(new InternetAddress(mailprops.get("com.att.dmaap.datarouter.mail.from").toString()));\r
521           \r
522           InternetAddress[] addressTo = new InternetAddress[emails.length];\r
523           for ( int x =0 ; x < emails.length; x++) {\r
524                addressTo[x] = new InternetAddress(emails[x]);\r
525           }\r
526           \r
527           msg.addRecipients(Message.RecipientType.TO, addressTo);\r
528           msg.setSubject(mailprops.get("com.att.dmaap.datarouter.mail.subject").toString());\r
529           htmlPart.setContent(mailprops.get("com.att.dmaap.datarouter.mail.body").toString().replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");\r
530           mp.addBodyPart(htmlPart);\r
531           msg.setContent(mp);\r
532           \r
533           System.out.println(mailprops.get("com.att.dmaap.datarouter.mail.body").toString().replace("[SERVER]", InetAddress.getLocalHost().getHostName()));\r
534         \r
535           Transport.send(msg);\r
536           intlogger.info("HTTPS relaxation mail is sent to - : "+email);\r
537           \r
538         } catch (AddressException e) {\r
539                   intlogger.error("Invalid email address, unable to send https relaxation mail to - : "+email);\r
540         } catch (MessagingException e) {\r
541                 intlogger.error("Invalid email address, unable to send https relaxation mail to - : "+email);\r
542         } \r
543         }\r
544 \r
545 \r
546         /**\r
547          * Get an array of all node names in the DR network.\r
548          * @return an array of Strings\r
549          */\r
550         public static String[] getNodes() {\r
551                 return nodes;\r
552         }\r
553         /**\r
554          * Get an array of all node InetAddresses in the DR network.\r
555          * @return an array of InetAddresses\r
556          */\r
557         public static InetAddress[] getNodeAddresses() {\r
558                 return nodeAddresses;\r
559         }\r
560         /**\r
561          * Get an array of all POD names in the DR network.\r
562          * @return an array of Strings\r
563          */\r
564         public static String[] getPods() {\r
565                 return new String[] { initial_active_pod, initial_standby_pod };\r
566         }\r
567         /**\r
568          * Get an array of all POD InetAddresses in the DR network.\r
569          * @return an array of InetAddresses\r
570          */\r
571         public static InetAddress[] getPodAddresses() {\r
572                 return podAddresses;\r
573         }\r
574         /**\r
575          * Gets the FQDN of the initially ACTIVE provisioning server (POD).\r
576          * Note: this used to be called isActivePOD(), however, that is a misnomer, as the active status\r
577          * could shift to the standby POD without these parameters changing.  Hence, the function names\r
578          * have been changed to more accurately reflect their purpose.\r
579          * @return the FQDN\r
580          */\r
581         public static boolean isInitialActivePOD() {\r
582                 return this_pod.equals(initial_active_pod);\r
583         }\r
584         /**\r
585          * Gets the FQDN of the initially STANDBY provisioning server (POD).\r
586          * Note: this used to be called isStandbyPOD(), however, that is a misnomer, as the standby status\r
587          * could shift to the active POD without these parameters changing.  Hence, the function names\r
588          * have been changed to more accurately reflect their purpose.\r
589          * @return the FQDN\r
590          */\r
591         public static boolean isInitialStandbyPOD() {\r
592                 return this_pod.equals(initial_standby_pod);\r
593         }\r
594         /**\r
595          * INSERT an {@link Insertable} bean into the database.\r
596          * @param bean the bean representing a row to insert\r
597          * @return true if the INSERT was successful\r
598          */\r
599         protected boolean doInsert(Insertable bean) {\r
600                 boolean rv = false;\r
601                 DB db = new DB();\r
602                 Connection conn = null;\r
603                 try {\r
604                         conn = db.getConnection();\r
605                         rv = bean.doInsert(conn);\r
606                 } catch (SQLException e) {\r
607                         rv = false;\r
608                         intlogger.warn("PROV0005 doInsert: "+e.getMessage());\r
609                         e.printStackTrace();\r
610                 } finally {\r
611                         if (conn != null)\r
612                                 db.release(conn);\r
613                 }\r
614                 return rv;\r
615         }\r
616         /**\r
617          * UPDATE an {@link Updateable} bean in the database.\r
618          * @param bean the bean representing a row to update\r
619          * @return true if the UPDATE was successful\r
620          */\r
621         protected boolean doUpdate(Updateable bean) {\r
622                 boolean rv = false;\r
623                 DB db = new DB();\r
624                 Connection conn = null;\r
625                 try {\r
626                         conn = db.getConnection();\r
627                         rv = bean.doUpdate(conn);\r
628                 } catch (SQLException e) {\r
629                         rv = false;\r
630                         intlogger.warn("PROV0006 doUpdate: "+e.getMessage());\r
631                         e.printStackTrace();\r
632                 } finally {\r
633                         if (conn != null)\r
634                                 db.release(conn);\r
635                 }\r
636                 return rv;\r
637         }\r
638         /**\r
639          * DELETE an {@link Deleteable} bean from the database.\r
640          * @param bean the bean representing a row to delete\r
641          * @return true if the DELETE was successful\r
642          */\r
643         protected boolean doDelete(Deleteable bean) {\r
644                 boolean rv = false;\r
645                 DB db = new DB();\r
646                 Connection conn = null;\r
647                 try {\r
648                         conn = db.getConnection();\r
649                         rv = bean.doDelete(conn);\r
650                 } catch (SQLException e) {\r
651                         rv = false;\r
652                         intlogger.warn("PROV0007 doDelete: "+e.getMessage());\r
653                         e.printStackTrace();\r
654                 } finally {\r
655                         if (conn != null)\r
656                                 db.release(conn);\r
657                 }\r
658                 return rv;\r
659         }\r
660         private static boolean getBoolean(Map<String,String> map, String name) {\r
661                 String s = map.get(name);\r
662                 return (s != null) && s.equalsIgnoreCase("true");\r
663         }\r
664         private static String getString(Map<String,String> map, String name, String dflt) {\r
665                 String s = map.get(name);\r
666                 return (s != null) ? s : dflt;\r
667         }\r
668         private static int getInt(Map<String,String> map, String name, int dflt) {\r
669                 try {\r
670                         String s = map.get(name);\r
671                         return Integer.parseInt(s);\r
672                 } catch (NumberFormatException e) {\r
673                         return dflt;\r
674                 }\r
675         }\r
676         private static Set<String> getSet(Map<String,String> map, String name) {\r
677                 Set<String> set = new HashSet<String>();\r
678                 String s = map.get(name);\r
679                 if (s != null) {\r
680                         String[] pp = s.split("\\|");\r
681                         if (pp != null) {\r
682                                 for (String t : pp) {\r
683                                         String t2 = t.trim();\r
684                                         if (t2.length() > 0)\r
685                                                 set.add(t2);\r
686                                 }\r
687                         }\r
688                 }\r
689                 return set;\r
690         }\r
691 \r
692         /**\r
693          * A class used to encapsulate a Content-type header, separating out the "version" attribute\r
694          * (which defaults to "1.0" if missing).\r
695          */\r
696         public class ContentHeader {\r
697                 private String type = "";\r
698                 private Map<String, String> map = new HashMap<String, String>();\r
699                 public ContentHeader() {\r
700                         this("", "1.0");\r
701                 }\r
702                 public ContentHeader(String t, String v) {\r
703                         type = t.trim();\r
704                         map.put("version", v);\r
705                 }\r
706                 public String getType() {\r
707                         return type;\r
708                 }\r
709                 public String getAttribute(String key) {\r
710                         String s = map.get(key);\r
711                         if (s == null)\r
712                                 s = "";\r
713                         return s;\r
714                 }\r
715         }\r
716 \r
717         /**\r
718          * Get the ContentHeader from an HTTP request.\r
719          * @param req the request\r
720          * @return the header, encapsulated in a ContentHeader object\r
721          */\r
722         public ContentHeader getContentHeader(HttpServletRequest req) {\r
723                 ContentHeader ch = new ContentHeader();\r
724                 String s = req.getHeader("Content-Type");\r
725                 if (s != null) {\r
726                         String[] pp = s.split(";");\r
727                         ch.type = pp[0].trim();\r
728                         for (int i = 1; i < pp.length; i++) {\r
729                                 int ix = pp[i].indexOf('=');\r
730                                 if (ix > 0) {\r
731                                         String k = pp[i].substring(0, ix).trim();\r
732                                         String v = pp[i].substring(ix+1).trim();\r
733                                         ch.map.put(k,  v);\r
734                                 } else {\r
735                                         ch.map.put(pp[i].trim(), "");\r
736                                 }\r
737                         }\r
738                 }\r
739                 return ch;\r
740         }\r
741         // Methods for the Policy Engine classes - ProvDataProvider interface\r
742         @Override\r
743         public String getFeedOwner(String feedId) {\r
744                 try {\r
745                         int n = Integer.parseInt(feedId);\r
746                         Feed f = Feed.getFeedById(n);\r
747                         if (f != null)\r
748                                 return f.getPublisher();\r
749                 } catch (NumberFormatException e) {\r
750                         // ignore\r
751                 }\r
752                 return null;\r
753         }\r
754         @Override\r
755         public String getFeedClassification(String feedId) {\r
756                 try {\r
757                         int n = Integer.parseInt(feedId);\r
758                         Feed f = Feed.getFeedById(n);\r
759                         if (f != null)\r
760                                 return f.getAuthorization().getClassification();\r
761                 } catch (NumberFormatException e) {\r
762                         // ignore\r
763                 }\r
764                 return null;\r
765         }\r
766         @Override\r
767         public String getSubscriptionOwner(String subId) {\r
768                 try {\r
769                         int n = Integer.parseInt(subId);\r
770                         Subscription s = Subscription.getSubscriptionById(n);\r
771                         if (s != null)\r
772                                 return s.getSubscriber();\r
773                 } catch (NumberFormatException e) {\r
774                         // ignore\r
775                 }\r
776                 return null;\r
777         }\r
778 \r
779         /*\r
780          * @Method - isUserMemberOfGroup - Rally:US708115 \r
781          * @Params - group object and user to check if exists in given group\r
782          * @return - boolean value /true/false\r
783          */\r
784         private boolean isUserMemberOfGroup(Group group, String user) {\r
785                          \r
786                 String groupdetails = group.getMembers().replace("]", "").replace("[", "");\r
787             String s[] =        groupdetails.split("},");\r
788                 \r
789                 for(int i=0; i < s.length; i++) {\r
790                                 JSONObject jsonObj = null;\r
791                                 try {\r
792                             jsonObj = new JSONObject(s[i]+"}");\r
793                             if(jsonObj.get("id").equals(user))\r
794                                 return true;\r
795                         } catch (JSONException e) {\r
796                             e.printStackTrace();\r
797                         }\r
798                 }\r
799                 return false;\r
800                 \r
801         }\r
802         \r
803         /*\r
804          * @Method - getGroupByFeedGroupId- Rally:US708115 \r
805          * @Params - User to check in group and feedid which is assigned the group.\r
806          * @return - string value grupid/null\r
807          */\r
808         @Override\r
809         public String getGroupByFeedGroupId(String owner, String feedId) {\r
810                 try {\r
811                         int n = Integer.parseInt(feedId);\r
812                         Feed f = Feed.getFeedById(n);\r
813                         if (f != null) {\r
814                                 int groupid = f.getGroupid();\r
815                                 if(groupid > 0) {\r
816                                         Group group = Group.getGroupById(groupid);\r
817                                         if(isUserMemberOfGroup(group, owner)) {\r
818                                                 return group.getAuthid();\r
819                                         }\r
820                                 }\r
821                         }\r
822                 } catch (NumberFormatException e) {\r
823                         // ignore\r
824                 }\r
825                 return null;\r
826         }\r
827         \r
828         /*\r
829          * @Method - getGroupBySubGroupId - Rally:US708115  \r
830          * @Params - User to check in group and subid which is assigned the group.\r
831          * @return - string value grupid/null\r
832          */\r
833         @Override\r
834         public String getGroupBySubGroupId(String owner, String subId) {\r
835                 try {\r
836                         int n = Integer.parseInt(subId);\r
837                         Subscription s = Subscription.getSubscriptionById(n);\r
838                         if (s != null) {\r
839                                 int groupid = s.getGroupid();\r
840                                 if(groupid > 0) {\r
841                                         Group group = Group.getGroupById(groupid);\r
842                                         if(isUserMemberOfGroup(group, owner)) {\r
843                                                 return group.getAuthid();\r
844                                         }\r
845                                 }\r
846                         }\r
847                 } catch (NumberFormatException e) {\r
848                         // ignore\r
849                 }\r
850                 return null;\r
851         }\r
852         \r
853         /*\r
854          * @Method - setIpAndFqdnForEelf - Rally:US664892  \r
855          * @Params - method, prints method name in EELF log.\r
856          */     \r
857         protected void setIpAndFqdnForEelf(String method) {\r
858                 MDC.clear();\r
859         MDC.put(MDC_SERVICE_NAME, method);\r
860         try {\r
861             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());\r
862             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());\r
863         } catch (Exception e) {\r
864             e.printStackTrace();\r
865         }\r
866 \r
867         }\r
868 }\r