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 com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
29 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
30 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
31 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.net.InetAddress;
38 import java.net.UnknownHostException;
39 import java.security.cert.X509Certificate;
40 import java.sql.Connection;
41 import java.sql.SQLException;
43 import javax.servlet.ServletConfig;
44 import javax.servlet.ServletException;
45 import javax.servlet.http.HttpServlet;
46 import javax.servlet.http.HttpServletRequest;
48 import com.att.eelf.configuration.EELFLogger;
49 import com.att.eelf.configuration.EELFManager;
50 import org.apache.commons.lang3.StringUtils;
51 import org.json.JSONArray;
52 import org.json.JSONException;
53 import org.json.JSONObject;
54 import org.json.JSONTokener;
55 import org.onap.dmaap.datarouter.authz.Authorizer;
56 import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;
57 import org.onap.dmaap.datarouter.authz.impl.ProvDataProvider;
58 import org.onap.dmaap.datarouter.provisioning.beans.*;
59 import org.onap.dmaap.datarouter.provisioning.utils.DB;
60 import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;
61 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
65 import javax.mail.internet.InternetAddress;
66 import javax.mail.internet.MimeBodyPart;
67 import javax.mail.internet.MimeMessage;
68 import javax.mail.internet.MimeMultipart;
69 import java.security.GeneralSecurityException;
71 import java.util.regex.Pattern;
75 * This is the base class for all Servlets in the provisioning code. It provides standard constants and some common
79 * @version $Id: BaseServlet.java,v 1.16 2014/03/12 19:45:40 eby Exp $
81 @SuppressWarnings("serial")
82 public class BaseServlet extends HttpServlet implements ProvDataProvider {
84 public static final String BEHALF_HEADER = "X-DMAAP-DR-ON-BEHALF-OF";
86 public static final String EXCLUDE_AAF_HEADER = "X-EXCLUDE-AAF";
88 private static final String AAF_CADI_FEED_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.feed.type";
89 private static final String AAF_CADI_SUB_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.sub.type";
90 private static final String AAF_INSTANCE = "org.onap.dmaap.datarouter.provserver.aaf.instance";
91 private static final String AAF_CADI_FEED = "org.onap.dmaap-dr.feed";
92 private static final String AAF_CADI_SUB = "org.onap.dmaap-dr.sub";
94 static final String CREATE_PERMISSION = "create";
95 static final String EDIT_PERMISSION = "edit";
96 static final String DELETE_PERMISSION = "delete";
97 static final String PUBLISH_PERMISSION = "publish";
98 static final String SUSPEND_PERMISSION = "suspend";
99 static final String RESTORE_PERMISSION = "restore";
100 static final String SUBSCRIBE_PERMISSION = "subscribe";
101 static final String APPROVE_SUB_PERMISSION = "approveSub";
103 static final String FEED_BASECONTENT_TYPE = "application/vnd.dmaap-dr.feed";
104 public static final String FEED_CONTENT_TYPE = "application/vnd.dmaap-dr.feed; version=2.0";
105 public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-full; version=2.0";
106 public static final String FEEDLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-list; version=1.0";
107 static final String SUB_BASECONTENT_TYPE = "application/vnd.dmaap-dr.subscription";
108 public static final String SUB_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription; version=2.0";
109 public static final String SUBFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-full; version=2.0";
110 static final String SUBLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-list; version=1.0";
113 //Adding groups functionality, ...1610
114 static final String GROUP_BASECONTENT_TYPE = "application/vnd.dmaap-dr.group";
115 static final String GROUP_CONTENT_TYPE = "application/vnd.dmaap-dr.group; version=2.0";
116 public static final String GROUPFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.group-full; version=2.0";
117 public static final String GROUPLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.fegrouped-list; version=1.0";
120 public static final String LOGLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.log-list; version=1.0";
121 public static final String PROVFULL_CONTENT_TYPE1 = "application/vnd.dmaap-dr.provfeed-full; version=1.0";
122 public static final String PROVFULL_CONTENT_TYPE2 = "application/vnd.dmaap-dr.provfeed-full; version=2.0";
123 public static final String CERT_ATTRIBUTE = "javax.servlet.request.X509Certificate";
125 static final String DB_PROBLEM_MSG = "There has been a problem with the DB. It is suggested you try the operation again.";
127 private static final int DEFAULT_MAX_FEEDS = 10000;
128 private static final int DEFAULT_MAX_SUBS = 100000;
129 private static final int DEFAULT_POKETIMER1 = 5;
130 private static final int DEFAULT_POKETIMER2 = 30;
131 private static final String DEFAULT_DOMAIN = "onap";
132 private static final String DEFAULT_PROVSRVR_NAME = "dmaap-dr-prov";
133 private static final String STATIC_ROUTING_NODES = ""; //Adding new param for static Routing - Rally:US664862-1610
136 public static final String MISSING_ON_BEHALF = "Missing X-DMAAP-DR-ON-BEHALF-OF header.";
137 public static final String MISSING_FEED = "Missing or bad feed number.";
138 public static final String POLICY_ENGINE = "Policy Engine disallows access.";
139 public static final String UNAUTHORIZED = "Unauthorized.";
140 public static final String BAD_SUB = "Missing or bad subscription number.";
141 public static final String BAD_JSON = "Badly formed JSON";
142 public static final String BAD_URL = "Bad URL.";
144 public static final String API = "/api/";
145 public static final String LOGS = "/logs/";
146 public static final String TEXT_CT = "text/plain";
147 public static final String INGRESS = "/ingress/";
148 public static final String EGRESS = "/egress/";
149 public static final String NETWORK = "/network/";
150 public static final String GROUPID = "groupid";
151 public static final String FEEDID = "feedid";
152 public static final String FEEDIDS = "feedids";
153 public static final String SUBID = "subid";
154 public static final String EVENT_TYPE = "eventType";
155 public static final String OUTPUT_TYPE = "output_type";
156 public static final String START_TIME = "start_time";
157 public static final String END_TIME = "end_time";
158 public static final String REASON_SQL = "reasonSQL";
162 * A boolean to trigger one time "provisioning changed" event on startup
164 private static boolean startmsgFlag = true;
166 * This POD should require SSL connections from clients; pulled from the DB (PROV_REQUIRE_SECURE)
168 private static boolean requireSecure = true;
170 * This POD should require signed, recognized certificates from clients; pulled from the DB (PROV_REQUIRE_CERT)
172 private static boolean requireCert = true;
174 * The set of authorized addresses and networks; pulled from the DB (PROV_AUTH_ADDRESSES)
176 private static Set<String> authorizedAddressesAndNetworks = new HashSet<>();
178 * The set of authorized names; pulled from the DB (PROV_AUTH_SUBJECTS)
180 private static Set<String> authorizedNames = new HashSet<>();
182 * The FQDN of the initially "active" provisioning server in this Data Router ecosystem
184 private static String initialActivePod;
186 * The FQDN of the initially "standby" provisioning server in this Data Router ecosystem
188 private static String initialStandbyPod;
190 * The FQDN of this provisioning server in this Data Router ecosystem
192 private static String thisPod;
194 * "Timer 1" - used to determine when to notify nodes of provisioning changes
196 private static long pokeTimer1;
198 * "Timer 2" - used to determine when to notify nodes of provisioning changes
200 private static long pokeTimer2;
202 * Array of nodes names and/or FQDNs
204 private static String[] nodes = new String[0];
206 * [DATARTR-27] Poke all the DR nodes : Array of nodes names and/or FQDNs
208 private static String[] drnodes = new String[0];
210 * Array of node IP addresses
212 private static InetAddress[] nodeAddresses = new InetAddress[0];
214 * Array of POD IP addresses
216 private static InetAddress[] podAddresses = new InetAddress[0];
218 * The maximum number of feeds allowed; pulled from the DB (PROV_MAXFEED_COUNT)
220 static int maxFeeds = 0;
222 * The maximum number of subscriptions allowed; pulled from the DB (PROV_MAXSUB_COUNT)
224 static int maxSubs = 0;
226 * The current number of feeds in the system
228 static int activeFeeds = 0;
230 * The current number of subscriptions in the system
232 static int activeSubs = 0;
235 * The domain used to generate a FQDN from the "bare" node names
237 private static String provDomain = "web.att.com";
240 * The standard FQDN of the provisioning server in this Data Router ecosystem
242 private static String provName = "feeds-drtr.web.att.com";
245 * The standard FQDN of the ACTIVE_POD provisioning server in this Data Router ecosystem
247 private static String activeProvName = "feeds-drtr.web.att.com";
249 //Adding new param for static Routing - Rally:US664862-1610
250 private static String staticRoutingNodes = STATIC_ROUTING_NODES;
253 * This logger is used to log provisioning events
255 protected static EELFLogger eventlogger;
257 * This logger is used to log internal events (errors, etc.)
259 protected static EELFLogger intlogger;
261 * Authorizer - interface to the Policy Engine
263 protected static Authorizer authz;
265 * The Synchronizer used to sync active DB to standby one
267 private static SynchronizerTask synctask = null;
269 //Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.
270 private InetAddress thishost;
271 private InetAddress loopback;
272 private static Boolean mailSendFlag = false;
274 private static final String MAILCONFIG_FILE = "mail.properties";
275 private static Properties mailprops;
277 //DMAAP-597 (Tech Dept) REST request source IP auth relaxation to accommodate OOM kubernetes deploy
278 private static String isAddressAuthEnabled = (new DB()).getProperties()
279 .getProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
281 static String isCadiEnabled = (new DB()).getProperties()
282 .getProperty("org.onap.dmaap.datarouter.provserver.cadi.enabled", "false");
285 * Initialize data common to all the provisioning server servlets.
287 protected BaseServlet() {
288 if(eventlogger == null) {
289 this.eventlogger = EELFManager.getInstance().getLogger("EventLog");
291 if(intlogger == null) {
292 this.intlogger = EELFManager.getInstance().getLogger("InternalLog");
295 authz = new ProvAuthorizer(this);
298 startmsgFlag = false;
299 provisioningParametersChanged();
301 if (synctask == null) {
302 synctask = SynchronizerTask.getSynchronizer();
304 String name = this.getClass().getName();
305 intlogger.info("PROV0002 Servlet " + name + " started.");
309 public void init(ServletConfig config) throws ServletException {
312 thishost = InetAddress.getLocalHost();
313 loopback = InetAddress.getLoopbackAddress();
314 } catch (UnknownHostException e) {
315 intlogger.info("BaseServlet.init: " + e.getMessage(), e);
319 public static int getIdFromPath(HttpServletRequest req) {
320 String path = req.getPathInfo();
321 if (path == null || path.length() < 2) {
325 return Integer.parseInt(path.substring(1));
326 } catch (NumberFormatException e) {
332 * Read the request's input stream and return a JSONObject from it
334 * @param req the HTTP request
335 * @return the JSONObject, or null if the stream cannot be parsed
337 JSONObject getJSONfromInput(HttpServletRequest req) {
338 JSONObject jo = null;
340 jo = new JSONObject(new JSONTokener(req.getInputStream()));
341 if (intlogger.isDebugEnabled()) {
342 intlogger.debug("JSON: " + jo.toString());
344 } catch (Exception e) {
345 intlogger.info("Error reading JSON: " + e);
351 * This method encrypt/decrypt the key in the JSON passed by user request inside the authorisation header object in request before logging the JSON.
353 * @param jo- the JSON passed in http request.
354 * @param maskKey- the key to be masked in the JSON passed.
355 * @param action- whether to mask the key or unmask it in a JSON passed.
356 * @return the JSONObject, or null if the stream cannot be parsed.
358 public static JSONObject maskJSON(JSONObject jo, String maskKey, boolean action) {
359 if (!jo.isNull("authorization")) {
360 JSONObject j2 = jo.getJSONObject("authorization");
361 JSONArray ja = j2.getJSONArray("endpoint_ids");
362 for (int i = 0; i < ja.length(); i++) {
363 if ((!ja.getJSONObject(i).isNull(maskKey))) {
364 String password = ja.getJSONObject(i).get(maskKey).toString();
367 ja.getJSONObject(i).put(maskKey, PasswordProcessor.encrypt(password));
369 ja.getJSONObject(i).put(maskKey, PasswordProcessor.decrypt(password));
371 } catch (JSONException | GeneralSecurityException e) {
372 intlogger.info("Error reading JSON while masking: " + e);
381 * Check if the remote host is authorized to perform provisioning. Is the request secure? Is it coming from an
382 * authorized IP address or network (configured via PROV_AUTH_ADDRESSES)? Does it have a valid client certificate
383 * (configured via PROV_AUTH_SUBJECTS)?
385 * @param request the request
386 * @return an error string, or null if all is OK
388 String isAuthorizedForProvisioning(HttpServletRequest request) {
389 if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
392 // Is the request https?
393 if (requireSecure && !request.isSecure()) {
394 return "Request must be made over an HTTPS connection.";
396 // Is remote IP authorized?
397 String remote = request.getRemoteAddr();
399 boolean found = false;
400 InetAddress ip = InetAddress.getByName(remote);
401 for (String addrnet : authorizedAddressesAndNetworks) {
402 found |= addressMatchesNetwork(ip, addrnet);
405 return "Unauthorized address: " + remote;
407 } catch (UnknownHostException e) {
408 intlogger.error("PROV0051 BaseServlet.isAuthorizedForProvisioning: " + e.getMessage(), e);
409 return "Unauthorized address: " + remote;
411 // Does remote have a valid certificate?
413 X509Certificate[] certs = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);
414 if (certs == null || certs.length == 0) {
415 return "Client certificate is missing.";
417 // cert[0] is the client cert
418 // see http://www.proto.research.att.com/java/java7/api/javax/net/ssl/SSLSession.html#getPeerCertificates()
419 String name = certs[0].getSubjectX500Principal().getName();
420 if (!authorizedNames.contains(name)) {
421 return "No authorized certificate found.";
429 * Check if the remote IP address is authorized to see the /internal URL tree.
431 * @param request the HTTP request
432 * @return true iff authorized
434 boolean isAuthorizedForInternal(HttpServletRequest request) {
436 if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
439 InetAddress ip = InetAddress.getByName(request.getRemoteAddr());
440 for (InetAddress node : getNodeAddresses()) {
441 if (node != null && ip.equals(node)) {
445 for (InetAddress pod : getPodAddresses()) {
446 if (pod != null && ip.equals(pod)) {
450 if (thishost != null && ip.equals(thishost)) {
453 if (loopback != null && ip.equals(loopback)) {
456 } catch (UnknownHostException e) {
457 intlogger.error("PROV0052 BaseServlet.isAuthorizedForInternal: " + e.getMessage(), e);
463 * Check if an IP address matches a network address.
465 * @param ip the IP address
466 * @param s the network address; a bare IP address may be matched also
467 * @return true if they intersect
469 private static boolean addressMatchesNetwork(InetAddress ip, String s) {
471 int n = s.indexOf("/");
473 mlen = Integer.parseInt(s.substring(n + 1));
474 s = s.substring(0, n);
477 InetAddress i2 = InetAddress.getByName(s);
478 byte[] b1 = ip.getAddress();
479 byte[] b2 = i2.getAddress();
480 if (b1.length != b2.length) {
485 (byte) 0x00, (byte) 0x80, (byte) 0xC0, (byte) 0xE0,
486 (byte) 0xF0, (byte) 0xF8, (byte) 0xFC, (byte) 0xFE
488 byte mask = masks[mlen % 8];
489 for (n = mlen / 8; n < b1.length; n++) {
495 for (n = 0; n < b1.length; n++) {
496 if (b1[n] != b2[n]) {
500 } catch (UnknownHostException e) {
501 intlogger.error("PROV0053 BaseServlet.addressMatchesNetwork: " + e.getMessage(), e);
508 * Something has changed in the provisioning data. Start the timers that will cause the pre-packaged JSON string to
509 * be regenerated, and cause nodes and the other provisioning server to be notified.
511 static void provisioningDataChanged() {
512 long now = System.currentTimeMillis();
513 Poker p = Poker.getPoker();
514 p.setTimers(now + (pokeTimer1 * 1000L), now + (pokeTimer2 * 1000L));
518 * Something in the parameters has changed, reload all parameters from the DB.
520 static void provisioningParametersChanged() {
521 Map<String, String> map = Parameters.getParameters();
522 requireSecure = getBoolean(map, Parameters.PROV_REQUIRE_SECURE);
523 requireCert = getBoolean(map, Parameters.PROV_REQUIRE_CERT);
524 authorizedAddressesAndNetworks = getSet(map, Parameters.PROV_AUTH_ADDRESSES);
525 authorizedNames = getSet(map, Parameters.PROV_AUTH_SUBJECTS);
526 nodes = getSet(map, Parameters.NODES).toArray(new String[0]);
527 maxFeeds = getInt(map, Parameters.PROV_MAXFEED_COUNT, DEFAULT_MAX_FEEDS);
528 maxSubs = getInt(map, Parameters.PROV_MAXSUB_COUNT, DEFAULT_MAX_SUBS);
529 pokeTimer1 = getInt(map, Parameters.PROV_POKETIMER1, DEFAULT_POKETIMER1);
530 pokeTimer2 = getInt(map, Parameters.PROV_POKETIMER2, DEFAULT_POKETIMER2);
532 * The domain used to generate a FQDN from the "bare" node names
534 provDomain = getString(map, Parameters.PROV_DOMAIN, DEFAULT_DOMAIN);
535 provName = getString(map, Parameters.PROV_NAME, DEFAULT_PROVSRVR_NAME);
536 activeProvName = getString(map, Parameters.PROV_ACTIVE_NAME, provName);
537 initialActivePod = getString(map, Parameters.ACTIVE_POD, "");
538 initialStandbyPod = getString(map, Parameters.STANDBY_POD, "");
539 staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
540 ""); //Adding new param for static Routing - Rally:US664862-1610
541 activeFeeds = Feed.countActiveFeeds();
542 activeSubs = Subscription.countActiveSubscriptions();
544 thisPod = InetAddress.getLocalHost().getHostName();
545 } catch (UnknownHostException e) {
547 intlogger.warn("PROV0014 Cannot determine the name of this provisioning server.", e);
550 // Normalize the nodes, and fill in nodeAddresses
551 InetAddress[] na = new InetAddress[nodes.length];
552 for (int i = 0; i < nodes.length; i++) {
554 na[i] = InetAddress.getByName(nodes[i]);
555 intlogger.debug("PROV0003 DNS lookup: " + nodes[i] + " => " + na[i].toString());
556 } catch (UnknownHostException e) {
558 intlogger.warn("PROV0004 Cannot lookup " + nodes[i] + ": " + e.getMessage(), e);
562 //[DATARTR-27] Poke all the DR nodes: assigning DR Nodes
563 drnodes = nodes.clone();
565 //Reset Nodes arr after - removing static routing Nodes, Rally Userstory - US664862 .
566 List<String> filterNodes = new ArrayList<>();
567 for (String node : nodes) {
568 if (!staticRoutingNodes.contains(node)) {
569 filterNodes.add(node);
572 nodes = filterNodes.toArray(new String[0]);
575 NodeClass.setNodes(nodes); // update NODES table
577 // Normalize the PODs, and fill in podAddresses
578 String[] pods = getPods();
579 na = new InetAddress[pods.length];
580 for (int i = 0; i < pods.length; i++) {
582 na[i] = InetAddress.getByName(pods[i]);
583 intlogger.debug("PROV0003 DNS lookup: " + pods[i] + " => " + na[i].toString());
584 } catch (UnknownHostException e) {
586 intlogger.warn("PROV0004 Cannot lookup " + pods[i] + ": " + e.getMessage(), e);
591 // Update ThrottleFilter
592 ThrottleFilter.configure();
594 // Check if we are active or standby POD
595 if (!isInitialActivePOD() && !isInitialStandbyPOD()) {
596 intlogger.warn("PROV0015 This machine is neither the active nor the standby POD.");
602 * Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047. Load mail properties.
606 private void loadMailProperties() {
607 if (mailprops == null) {
608 mailprops = new Properties();
609 try (InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE)) {
610 mailprops.load(inStream);
611 } catch (IOException e) {
612 intlogger.error("PROV9003 Opening properties: " + e.getMessage(), e);
620 * Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.
622 * @param email - list of email ids to notify if HTTP relexcation is enabled.
625 private void notifyPSTeam(String email) {
626 loadMailProperties(); //Load HTTPS Relex mail properties.
627 String[] emails = email.split(Pattern.quote("|"));
629 Properties mailproperties = new Properties();
630 mailproperties.put("mail.smtp.host", mailprops.get("com.att.dmaap.datarouter.mail.server"));
631 mailproperties.put("mail.transport.protocol", mailprops.get("com.att.dmaap.datarouter.mail.protocol"));
633 Session session = Session.getDefaultInstance(mailproperties, null);
634 Multipart mp = new MimeMultipart();
635 MimeBodyPart htmlPart = new MimeBodyPart();
639 Message msg = new MimeMessage(session);
640 msg.setFrom(new InternetAddress(mailprops.get("com.att.dmaap.datarouter.mail.from").toString()));
642 InternetAddress[] addressTo = new InternetAddress[emails.length];
643 for (int x = 0; x < emails.length; x++) {
644 addressTo[x] = new InternetAddress(emails[x]);
647 msg.addRecipients(Message.RecipientType.TO, addressTo);
648 msg.setSubject(mailprops.get("com.att.dmaap.datarouter.mail.subject").toString());
649 htmlPart.setContent(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
650 .replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");
651 mp.addBodyPart(htmlPart);
654 intlogger.info(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
655 .replace("[SERVER]", InetAddress.getLocalHost().getHostName()));
658 intlogger.info("HTTPS relaxation mail is sent to - : " + email);
660 } catch (MessagingException e) {
661 intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email, e);
662 } catch (UnknownHostException uhe) {
663 intlogger.error("UnknownHostException", uhe);
667 public static String getProvName() {
671 public static String getActiveProvName() {
672 return activeProvName;
676 * Get an array of all node names in the DR network.
678 * @return an array of Strings
680 public static String[] getNodes() {
685 * [DATARTR-27] Poke all the DR nodes
686 * Get an array of all node names in the DR network.
688 * @return an array of Strings
690 public static String[] getDRNodes() {
695 * Get an array of all node InetAddresses in the DR network.
697 * @return an array of InetAddresses
699 public static InetAddress[] getNodeAddresses() {
700 return nodeAddresses;
704 * Get an array of all POD names in the DR network.
706 * @return an array of Strings
708 public static String[] getPods() {
709 return new String[]{initialActivePod, initialStandbyPod};
713 * Get an array of all POD InetAddresses in the DR network.
715 * @return an array of InetAddresses
717 private static InetAddress[] getPodAddresses() {
722 * Gets the FQDN of the initially ACTIVE_POD provisioning server (POD). Note: this used to be called isActivePOD(),
723 * however, that is a misnomer, as the active status could shift to the standby POD without these parameters
724 * changing. Hence, the function names have been changed to more accurately reflect their purpose.
728 public static boolean isInitialActivePOD() {
729 return thisPod.equals(initialActivePod);
733 * Gets the FQDN of the initially STANDBY_POD provisioning server (POD). Note: this used to be called isStandbyPOD(),
734 * however, that is a misnomer, as the standby status could shift to the active POD without these parameters
735 * changing. Hence, the function names have been changed to more accurately reflect their purpose.
739 public static boolean isInitialStandbyPOD() {
740 return thisPod.equals(initialStandbyPod);
744 * INSERT an {@link Insertable} bean into the database.
746 * @param bean the bean representing a row to insert
747 * @return true if the INSERT was successful
749 protected boolean doInsert(Insertable bean) {
752 Connection conn = null;
754 conn = db.getConnection();
755 rv = bean.doInsert(conn);
756 } catch (SQLException e) {
758 intlogger.warn("PROV0005 doInsert: " + e.getMessage(), e);
768 * UPDATE an {@link Updateable} bean in the database.
770 * @param bean the bean representing a row to update
771 * @return true if the UPDATE was successful
773 protected boolean doUpdate(Updateable bean) {
776 Connection conn = null;
778 conn = db.getConnection();
779 rv = bean.doUpdate(conn);
780 } catch (SQLException e) {
782 intlogger.warn("PROV0006 doUpdate: " + e.getMessage(), e);
792 * DELETE an {@link Deleteable} bean from the database.
794 * @param bean the bean representing a row to delete
795 * @return true if the DELETE was successful
797 protected boolean doDelete(Deleteable bean) {
800 Connection conn = null;
802 conn = db.getConnection();
803 rv = bean.doDelete(conn);
804 } catch (SQLException e) {
806 intlogger.warn("PROV0007 doDelete: " + e.getMessage(), e);
815 private static boolean getBoolean(Map<String, String> map, String name) {
816 String s = map.get(name);
817 return (s != null) && "true".equalsIgnoreCase(s);
820 private static String getString(Map<String, String> map, String name, String dflt) {
821 String s = map.get(name);
822 return (s != null) ? s : dflt;
825 private static int getInt(Map<String, String> map, String name, int dflt) {
827 String s = map.get(name);
828 return Integer.parseInt(s);
829 } catch (NumberFormatException e) {
834 private static Set<String> getSet(Map<String, String> map, String name) {
835 Set<String> set = new HashSet<>();
836 String s = map.get(name);
838 String[] pp = s.split("\\|");
840 for (String t : pp) {
841 String t2 = t.trim();
842 if (t2.length() > 0) {
852 * A class used to encapsulate a Content-type header, separating out the "version" attribute (which defaults to
855 public class ContentHeader {
857 private String type = "";
858 private Map<String, String> map = new HashMap<>();
864 ContentHeader(String t, String v) {
866 map.put("version", v);
869 public String getType() {
873 public String getAttribute(String key) {
874 String s = map.get(key);
883 * Get the ContentHeader from an HTTP request.
885 * @param req the request
886 * @return the header, encapsulated in a ContentHeader object
888 ContentHeader getContentHeader(HttpServletRequest req) {
889 ContentHeader ch = new ContentHeader();
890 String s = req.getHeader("Content-Type");
892 String[] pp = s.split(";");
893 ch.type = pp[0].trim();
894 for (int i = 1; i < pp.length; i++) {
895 int ix = pp[i].indexOf('=');
897 String k = pp[i].substring(0, ix).trim();
898 String v = pp[i].substring(ix + 1).trim();
901 ch.map.put(pp[i].trim(), "");
908 // Methods for the Policy Engine classes - ProvDataProvider interface
910 public String getFeedOwner(String feedId) {
912 int n = Integer.parseInt(feedId);
913 Feed f = Feed.getFeedById(n);
915 return f.getPublisher();
917 } catch (NumberFormatException e) {
924 public String getFeedClassification(String feedId) {
926 int n = Integer.parseInt(feedId);
927 Feed f = Feed.getFeedById(n);
929 return f.getAuthorization().getClassification();
931 } catch (NumberFormatException e) {
938 public String getSubscriptionOwner(String subId) {
940 int n = Integer.parseInt(subId);
941 Subscription s = Subscription.getSubscriptionById(n);
943 return s.getSubscriber();
945 } catch (NumberFormatException e) {
952 * @Method - isUserMemberOfGroup - Rally:US708115
953 * @Params - group object and user to check if exists in given group
954 * @return - boolean value /true/false
956 private boolean isUserMemberOfGroup(Group group, String user) {
958 String groupDetails = group.getMembers().replace("]", "").replace("[", "");
959 String[] s = groupDetails.split("},");
961 for (String value : s) {
964 jsonObj = new JSONObject(value + "}");
965 if (jsonObj.get("id").equals(user)) {
968 } catch (JSONException e) {
969 intlogger.error("JSONException: " + e.getMessage(), e);
977 * @Method - getGroupByFeedGroupId- Rally:US708115
978 * @Params - User to check in group and feedid which is assigned the group.
979 * @return - string value grupid/null
982 public String getGroupByFeedGroupId(String owner, String feedId) {
984 int n = Integer.parseInt(feedId);
985 Feed f = Feed.getFeedById(n);
987 int groupid = f.getGroupid();
989 Group group = Group.getGroupById(groupid);
990 assert group != null;
991 if (isUserMemberOfGroup(group, owner)) {
992 return group.getAuthid();
996 } catch (NumberFormatException e) {
1003 * @Method - getGroupBySubGroupId - Rally:US708115
1004 * @Params - User to check in group and subid which is assigned the group.
1005 * @return - string value grupid/null
1008 public String getGroupBySubGroupId(String owner, String subId) {
1010 int n = Integer.parseInt(subId);
1011 Subscription s = Subscription.getSubscriptionById(n);
1013 int groupid = s.getGroupid();
1015 Group group = Group.getGroupById(groupid);
1016 assert group != null;
1017 if (isUserMemberOfGroup(group, owner)) {
1018 return group.getAuthid();
1022 } catch (NumberFormatException e) {
1029 * @Method - setIpFqdnRequestIDandInvocationIDForEelf
1030 * @Params - method, prints method name in EELF log.
1031 * @Params- Req, Request used to get RequestId and InvocationId
1033 void setIpFqdnRequestIDandInvocationIDForEelf(String method, HttpServletRequest req) {
1034 setIpFqdnForEelf(method);
1035 setMDC(req, "X-ONAP-RequestID", MDC_KEY_REQUEST_ID);
1036 setMDC(req, "X-InvocationID", "InvocationId");
1039 private void setMDC(HttpServletRequest req, String headerName, String keyName) {
1040 String mdcId = req.getHeader(headerName);
1041 if (StringUtils.isBlank(mdcId)) {
1042 mdcId = UUID.randomUUID().toString();
1044 MDC.put(keyName, mdcId);
1048 * @Method - setIpFqdnRequestIdForEelf - Rally:US664892
1049 * @Params - method, prints method name in EELF log.
1051 void setIpFqdnForEelf(String method) {
1053 MDC.put(MDC_SERVICE_NAME, method);
1055 MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
1056 MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
1057 } catch (Exception e) {
1058 intlogger.error("Exception: " + e.getMessage(), e);
1064 * AAF changes: TDP EPIC US# 307413
1065 * @Method - getFeedPermission - Forming permission string for feed part to check AAF access in CADI Framework
1066 * @Params - aafInstance Passing aafInstance as it's used in permission string
1067 * @Params - userAction Passing CONST values to set different actions in permission string
1069 String getFeedPermission(String aafInstance, String userAction) {
1071 Properties props = (new DB()).getProperties();
1072 String type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
1074 switch (userAction) {
1075 case CREATE_PERMISSION:
1076 action = CREATE_PERMISSION;
1078 case EDIT_PERMISSION:
1079 action = EDIT_PERMISSION;
1081 case DELETE_PERMISSION:
1082 action = DELETE_PERMISSION;
1084 case PUBLISH_PERMISSION:
1085 action = PUBLISH_PERMISSION;
1087 case SUSPEND_PERMISSION:
1088 action = SUSPEND_PERMISSION;
1090 case RESTORE_PERMISSION:
1091 action = RESTORE_PERMISSION;
1096 if (aafInstance == null || "".equals(aafInstance)) {
1097 aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
1099 return type + "|" + aafInstance + "|" + action;
1100 } catch (Exception e) {
1101 intlogger.error("PROV7005 BaseServlet.getFeedPermission: " + e.getMessage(), e);
1107 * AAF changes: TDP EPIC US# 307413
1108 * @Method - getSubscriberPermission - Forming permission string for subscription part to check AAF access in CADI Framework
1109 * @Params - aafInstance Passing aafInstance as it's used in permission string
1110 * @Params - userAction Passing CONST values to set different actions in permission string
1112 String getSubscriberPermission(String aafInstance, String userAction) {
1114 Properties props = (new DB()).getProperties();
1115 String type = props.getProperty(AAF_CADI_SUB_TYPE, AAF_CADI_SUB);
1117 switch (userAction) {
1118 case SUBSCRIBE_PERMISSION:
1119 action = SUBSCRIBE_PERMISSION;
1120 type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
1122 case EDIT_PERMISSION:
1123 action = EDIT_PERMISSION;
1125 case DELETE_PERMISSION:
1126 action = DELETE_PERMISSION;
1128 case RESTORE_PERMISSION:
1129 action = RESTORE_PERMISSION;
1131 case SUSPEND_PERMISSION:
1132 action = SUSPEND_PERMISSION;
1134 case PUBLISH_PERMISSION:
1135 action = PUBLISH_PERMISSION;
1137 case APPROVE_SUB_PERMISSION:
1138 action = APPROVE_SUB_PERMISSION;
1139 type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
1144 if (aafInstance == null || "".equals(aafInstance)) {
1145 aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
1147 return type + "|" + aafInstance + "|" + action;
1148 } catch (Exception e) {
1149 intlogger.error("PROV7005 BaseServlet.getSubscriberPermission: " + e.getMessage(), e);