Remove major and minor code smells in dr-prov
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / BaseServlet.java
old mode 100644 (file)
new mode 100755 (executable)
index 6ed5d8b..7475b6b
@@ -28,6 +28,9 @@ import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
 
 import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
 import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+
+
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -36,49 +39,37 @@ import java.net.UnknownHostException;
 import java.security.cert.X509Certificate;
 import java.sql.Connection;
 import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 
-import org.apache.log4j.Logger;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONArray;
+import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONTokener;
 import org.onap.dmaap.datarouter.authz.Authorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;
 import org.onap.dmaap.datarouter.authz.impl.ProvDataProvider;
-import org.onap.dmaap.datarouter.provisioning.beans.Deleteable;
-import org.onap.dmaap.datarouter.provisioning.beans.Feed;
-import org.onap.dmaap.datarouter.provisioning.beans.Group;
-import org.onap.dmaap.datarouter.provisioning.beans.Insertable;
-import org.onap.dmaap.datarouter.provisioning.beans.NodeClass;
-import org.onap.dmaap.datarouter.provisioning.beans.Parameters;
-import org.onap.dmaap.datarouter.provisioning.beans.Subscription;
-import org.onap.dmaap.datarouter.provisioning.beans.Updateable;
+import org.onap.dmaap.datarouter.provisioning.beans.*;
 import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.onap.dmaap.datarouter.provisioning.utils.PasswordProcessor;
 import org.onap.dmaap.datarouter.provisioning.utils.ThrottleFilter;
-import org.json.JSONException;
 import org.slf4j.MDC;
 
-import java.util.Properties;
-import java.util.regex.Pattern;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.AddressException;
+import javax.mail.*;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
+import java.security.GeneralSecurityException;
+import java.util.*;
+import java.util.regex.Pattern;
+
 
 /**
  * This is the base class for all Servlets in the provisioning code. It provides standard constants and some common
@@ -90,27 +81,45 @@ import javax.mail.internet.MimeMultipart;
 @SuppressWarnings("serial")
 public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
-    public static final String BEHALF_HEADER = "X-ATT-DR-ON-BEHALF-OF";
-    static final String FEED_BASECONTENT_TYPE = "application/vnd.att-dr.feed";
-    public static final String FEED_CONTENT_TYPE = "application/vnd.att-dr.feed; version=2.0";
-    public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.att-dr.feed-full; version=2.0";
-    public static final String FEEDLIST_CONTENT_TYPE = "application/vnd.att-dr.feed-list; version=1.0";
-    static final String SUB_BASECONTENT_TYPE = "application/vnd.att-dr.subscription";
-    public static final String SUB_CONTENT_TYPE = "application/vnd.att-dr.subscription; version=2.0";
-    public static final String SUBFULL_CONTENT_TYPE = "application/vnd.att-dr.subscription-full; version=2.0";
-    static final String SUBLIST_CONTENT_TYPE = "application/vnd.att-dr.subscription-list; version=1.0";
+    public static final String BEHALF_HEADER = "X-DMAAP-DR-ON-BEHALF-OF";
+
+    public static final String EXCLUDE_AAF_HEADER = "X-EXCLUDE-AAF";
+
+    private static final String AAF_CADI_FEED_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.feed.type";
+    private static final String AAF_CADI_SUB_TYPE = "org.onap.dmaap.datarouter.provserver.aaf.sub.type";
+    private static final String AAF_INSTANCE = "org.onap.dmaap.datarouter.provserver.aaf.instance";
+    private static final String AAF_CADI_FEED = "org.onap.dmaap-dr.feed";
+    private static final String AAF_CADI_SUB = "org.onap.dmaap-dr.sub";
+
+    static final String CREATE_PERMISSION = "create";
+    static final String EDIT_PERMISSION = "edit";
+    static final String DELETE_PERMISSION = "delete";
+    static final String PUBLISH_PERMISSION = "publish";
+    static final String SUSPEND_PERMISSION = "suspend";
+    static final String RESTORE_PERMISSION = "restore";
+    static final String SUBSCRIBE_PERMISSION = "subscribe";
+    static final String APPROVE_SUB_PERMISSION = "approveSub";
+
+    static final String FEED_BASECONTENT_TYPE = "application/vnd.dmaap-dr.feed";
+    public static final String FEED_CONTENT_TYPE = "application/vnd.dmaap-dr.feed; version=2.0";
+    public static final String FEEDFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-full; version=2.0";
+    public static final String FEEDLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.feed-list; version=1.0";
+    static final String SUB_BASECONTENT_TYPE = "application/vnd.dmaap-dr.subscription";
+    public static final String SUB_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription; version=2.0";
+    public static final String SUBFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-full; version=2.0";
+    static final String SUBLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.subscription-list; version=1.0";
 
 
     //Adding groups functionality, ...1610
-    static final String GROUP_BASECONTENT_TYPE = "application/vnd.att-dr.group";
-    public static final String GROUP_CONTENT_TYPE = "application/vnd.att-dr.group; version=2.0";
-    static final String GROUPFULL_CONTENT_TYPE = "application/vnd.att-dr.group-full; version=2.0";
-    public static final String GROUPLIST_CONTENT_TYPE = "application/vnd.att-dr.fegrouped-list; version=1.0";
+    static final String GROUP_BASECONTENT_TYPE = "application/vnd.dmaap-dr.group";
+    static final String GROUP_CONTENT_TYPE = "application/vnd.dmaap-dr.group; version=2.0";
+    public static final String GROUPFULL_CONTENT_TYPE = "application/vnd.dmaap-dr.group-full; version=2.0";
+    public static final String GROUPLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.fegrouped-list; version=1.0";
 
 
-    public static final String LOGLIST_CONTENT_TYPE = "application/vnd.att-dr.log-list; version=1.0";
-    public static final String PROVFULL_CONTENT_TYPE1 = "application/vnd.att-dr.provfeed-full; version=1.0";
-    public static final String PROVFULL_CONTENT_TYPE2 = "application/vnd.att-dr.provfeed-full; version=2.0";
+    public static final String LOGLIST_CONTENT_TYPE = "application/vnd.dmaap-dr.log-list; version=1.0";
+    public static final String PROVFULL_CONTENT_TYPE1 = "application/vnd.dmaap-dr.provfeed-full; version=1.0";
+    public static final String PROVFULL_CONTENT_TYPE2 = "application/vnd.dmaap-dr.provfeed-full; version=2.0";
     public static final String CERT_ATTRIBUTE = "javax.servlet.request.X509Certificate";
 
     static final String DB_PROBLEM_MSG = "There has been a problem with the DB.  It is suggested you try the operation again.";
@@ -121,9 +130,34 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     private static final int DEFAULT_POKETIMER2 = 30;
     private static final String DEFAULT_DOMAIN = "onap";
     private static final String DEFAULT_PROVSRVR_NAME = "dmaap-dr-prov";
-    private static final String RESEARCH_SUBNET = "10.42.0.0/16";
     private static final String STATIC_ROUTING_NODES = ""; //Adding new param for static Routing - Rally:US664862-1610
 
+    //Common Errors
+    public static final String MISSING_ON_BEHALF = "Missing X-DMAAP-DR-ON-BEHALF-OF header.";
+    public static final String MISSING_FEED = "Missing or bad feed number.";
+    public static final String POLICY_ENGINE = "Policy Engine disallows access.";
+    public static final String UNAUTHORIZED = "Unauthorized.";
+    public static final String BAD_SUB = "Missing or bad subscription number.";
+    public static final String BAD_JSON = "Badly formed JSON";
+    public static final String BAD_URL = "Bad URL.";
+
+    public static final String API = "/api/";
+    public static final String LOGS = "/logs/";
+    public static final String TEXT_CT = "text/plain";
+    public static final String INGRESS = "/ingress/";
+    public static final String EGRESS = "/egress/";
+    public static final String NETWORK = "/network/";
+    public static final String GROUPID = "groupid";
+    public static final String FEEDID = "feedid";
+    public static final String FEEDIDS = "feedids";
+    public static final String SUBID = "subid";
+    public static final String EVENT_TYPE = "eventType";
+    public static final String OUTPUT_TYPE = "output_type";
+    public static final String START_TIME = "start_time";
+    public static final String END_TIME = "end_time";
+    public static final String REASON_SQL = "reasonSQL";
+
+
     /**
      * A boolean to trigger one time "provisioning changed" event on startup
      */
@@ -139,11 +173,11 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     /**
      * The set of authorized addresses and networks; pulled from the DB (PROV_AUTH_ADDRESSES)
      */
-    private static Set<String> authorizedAddressesAndNetworks = new HashSet<String>();
+    private static Set<String> authorizedAddressesAndNetworks = new HashSet<>();
     /**
      * The set of authorized names; pulled from the DB (PROV_AUTH_SUBJECTS)
      */
-    private static Set<String> authorizedNames = new HashSet<String>();
+    private static Set<String> authorizedNames = new HashSet<>();
     /**
      * The FQDN of the initially "active" provisioning server in this Data Router ecosystem
      */
@@ -168,6 +202,10 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Array of nodes names and/or FQDNs
      */
     private static String[] nodes = new String[0];
+    /**
+     * [DATARTR-27] Poke all the DR nodes : Array of nodes names and/or FQDNs
+     */
+    private static String[] drnodes = new String[0];
     /**
      * Array of node IP addresses
      */
@@ -192,36 +230,33 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * The current number of subscriptions in the system
      */
     static int activeSubs = 0;
+
     /**
      * The domain used to generate a FQDN from the "bare" node names
      */
     private static String provDomain = "web.att.com";
+
     /**
      * The standard FQDN of the provisioning server in this Data Router ecosystem
      */
-    public static String provName = "feeds-drtr.web.att.com";
+    private static String provName = "feeds-drtr.web.att.com";
+
     /**
      * The standard FQDN of the ACTIVE provisioning server in this Data Router ecosystem
      */
-    public static String activeProvName = "feeds-drtr.web.att.com";
-    /**
-     * Special subnet that is allowed access to /internal
-     */
-    private static String researchSubnet = RESEARCH_SUBNET;
-    /**
-     * Special subnet that is allowed access to /internal to Lab Machine
-     */
-    private static String researchSubnet1 = RESEARCH_SUBNET;
-    private static String staticRoutingNodes = STATIC_ROUTING_NODES; //Adding new param for static Routing - Rally:US664862-1610
+    private static String activeProvName = "feeds-drtr.web.att.com";
+
+    //Adding new param for static Routing - Rally:US664862-1610
+    private static String staticRoutingNodes = STATIC_ROUTING_NODES;
 
     /**
      * This logger is used to log provisioning events
      */
-    protected static Logger eventlogger;
+    protected static EELFLogger eventlogger;
     /**
      * This logger is used to log internal events (errors, etc.)
      */
-    protected static Logger intlogger;
+    protected static EELFLogger intlogger;
     /**
      * Authorizer - interface to the Policy Engine
      */
@@ -241,17 +276,20 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     //DMAAP-597 (Tech Dept) REST request source IP auth relaxation to accommodate OOM kubernetes deploy
     private static String isAddressAuthEnabled = (new DB()).getProperties()
-        .getProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
+            .getProperty("org.onap.dmaap.datarouter.provserver.isaddressauthenabled", "false");
+
+    static String isCadiEnabled = (new DB()).getProperties()
+            .getProperty("org.onap.dmaap.datarouter.provserver.cadi.enabled", "false");
 
     /**
      * Initialize data common to all the provisioning server servlets.
      */
     protected BaseServlet() {
-        if (eventlogger == null) {
-            eventlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.events");
+        if(eventlogger == null) {
+            this.eventlogger = EELFManager.getInstance().getLogger("EventLog");
         }
-        if (intlogger == null) {
-            intlogger = Logger.getLogger("org.onap.dmaap.datarouter.provisioning.internal");
+        if(intlogger == null) {
+            this.intlogger = EELFManager.getInstance().getLogger("InternalLog");
         }
         if (authz == null) {
             authz = new ProvAuthorizer(this);
@@ -273,13 +311,12 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         try {
             thishost = InetAddress.getLocalHost();
             loopback = InetAddress.getLoopbackAddress();
-            checkHttpsRelaxation(); //Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.
         } catch (UnknownHostException e) {
-            // ignore
+            intlogger.info("BaseServlet.init: " + e.getMessage(), e);
         }
     }
 
-    int getIdFromPath(HttpServletRequest req) {
+    public static int getIdFromPath(HttpServletRequest req) {
         String path = req.getPathInfo();
         if (path == null || path.length() < 2) {
             return -1;
@@ -310,6 +347,36 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         return jo;
     }
 
+    /**
+     * This method encrypt/decrypt the key in the JSON passed by user request inside the authorisation header object in request before logging the JSON.
+     *
+     * @param jo-      the JSON passed in http request.
+     * @param maskKey- the key to be masked in the JSON passed.
+     * @param action-  whether to mask the key or unmask it in a JSON passed.
+     * @return the JSONObject, or null if the stream cannot be parsed.
+     */
+    public static JSONObject maskJSON(JSONObject jo, String maskKey, boolean action) {
+        if (!jo.isNull("authorization")) {
+            JSONObject j2 = jo.getJSONObject("authorization");
+            JSONArray ja = j2.getJSONArray("endpoint_ids");
+            for (int i = 0; i < ja.length(); i++) {
+                if ((!ja.getJSONObject(i).isNull(maskKey))) {
+                    String password = ja.getJSONObject(i).get(maskKey).toString();
+                    try {
+                        if (action) {
+                            ja.getJSONObject(i).put(maskKey, PasswordProcessor.encrypt(password));
+                        } else {
+                            ja.getJSONObject(i).put(maskKey, PasswordProcessor.decrypt(password));
+                        }
+                    } catch (JSONException | GeneralSecurityException e) {
+                        intlogger.info("Error reading JSON while masking: " + e);
+                    }
+                }
+            }
+        }
+        return jo;
+    }
+
     /**
      * Check if the remote host is authorized to perform provisioning. Is the request secure? Is it coming from an
      * authorized IP address or network (configured via PROV_AUTH_ADDRESSES)? Does it have a valid client certificate
@@ -319,14 +386,13 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * @return an error string, or null if all is OK
      */
     String isAuthorizedForProvisioning(HttpServletRequest request) {
-        if (Boolean.parseBoolean(isAddressAuthEnabled)) {
+        if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
             return null;
         }
         // Is the request https?
         if (requireSecure && !request.isSecure()) {
             return "Request must be made over an HTTPS connection.";
         }
-
         // Is remote IP authorized?
         String remote = request.getRemoteAddr();
         try {
@@ -339,12 +405,12 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 return "Unauthorized address: " + remote;
             }
         } catch (UnknownHostException e) {
+            intlogger.error("PROV0051 BaseServlet.isAuthorizedForProvisioning: " + e.getMessage(), e);
             return "Unauthorized address: " + remote;
         }
-
         // Does remote have a valid certificate?
         if (requireCert) {
-            X509Certificate certs[] = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);
+            X509Certificate[] certs = (X509Certificate[]) request.getAttribute(CERT_ATTRIBUTE);
             if (certs == null || certs.length == 0) {
                 return "Client certificate is missing.";
             }
@@ -355,7 +421,6 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 return "No authorized certificate found.";
             }
         }
-
         // No problems!
         return null;
     }
@@ -367,9 +432,8 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * @return true iff authorized
      */
     boolean isAuthorizedForInternal(HttpServletRequest request) {
-
         try {
-            if (Boolean.parseBoolean(isAddressAuthEnabled)) {
+            if (!Boolean.parseBoolean(isAddressAuthEnabled)) {
                 return true;
             }
             InetAddress ip = InetAddress.getByName(request.getRemoteAddr());
@@ -389,15 +453,8 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             if (loopback != null && ip.equals(loopback)) {
                 return true;
             }
-            // Also allow the "special subnet" access
-            if (addressMatchesNetwork(ip, researchSubnet1)) {
-                return true;
-            }
-            if (addressMatchesNetwork(ip, researchSubnet)) {
-                return true;
-            }
         } catch (UnknownHostException e) {
-            // ignore
+            intlogger.error("PROV0052 BaseServlet.isAuthorizedForInternal: " + e.getMessage(), e);
         }
         return false;
     }
@@ -406,7 +463,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Check if an IP address matches a network address.
      *
      * @param ip the IP address
-     * @param s the network address; a bare IP address may be matched also
+     * @param s  the network address; a bare IP address may be matched also
      * @return true if they intersect
      */
     private static boolean addressMatchesNetwork(InetAddress ip, String s) {
@@ -425,8 +482,8 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             }
             if (mlen > 0) {
                 byte[] masks = {
-                    (byte) 0x00, (byte) 0x80, (byte) 0xC0, (byte) 0xE0,
-                    (byte) 0xF0, (byte) 0xF8, (byte) 0xFC, (byte) 0xFE
+                        (byte) 0x00, (byte) 0x80, (byte) 0xC0, (byte) 0xE0,
+                        (byte) 0xF0, (byte) 0xF8, (byte) 0xFC, (byte) 0xFE
                 };
                 byte mask = masks[mlen % 8];
                 for (n = mlen / 8; n < b1.length; n++) {
@@ -441,6 +498,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 }
             }
         } catch (UnknownHostException e) {
+            intlogger.error("PROV0053 BaseServlet.addressMatchesNetwork: " + e.getMessage(), e);
             return false;
         }
         return true;
@@ -450,7 +508,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * Something has changed in the provisioning data. Start the timers that will cause the pre-packaged JSON string to
      * be regenerated, and cause nodes and the other provisioning server to be notified.
      */
-    public static void provisioningDataChanged() {
+    static void provisioningDataChanged() {
         long now = System.currentTimeMillis();
         Poker p = Poker.getPoker();
         p.setTimers(now + (pokeTimer1 * 1000L), now + (pokeTimer2 * 1000L));
@@ -459,7 +517,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     /**
      * Something in the parameters has changed, reload all parameters from the DB.
      */
-    public static void provisioningParametersChanged() {
+    static void provisioningParametersChanged() {
         Map<String, String> map = Parameters.getParameters();
         requireSecure = getBoolean(map, Parameters.PROV_REQUIRE_SECURE);
         requireCert = getBoolean(map, Parameters.PROV_REQUIRE_CERT);
@@ -470,40 +528,40 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         maxSubs = getInt(map, Parameters.PROV_MAXSUB_COUNT, DEFAULT_MAX_SUBS);
         pokeTimer1 = getInt(map, Parameters.PROV_POKETIMER1, DEFAULT_POKETIMER1);
         pokeTimer2 = getInt(map, Parameters.PROV_POKETIMER2, DEFAULT_POKETIMER2);
+        /**
+         * The domain used to generate a FQDN from the "bare" node names
+         */
         provDomain = getString(map, Parameters.PROV_DOMAIN, DEFAULT_DOMAIN);
         provName = getString(map, Parameters.PROV_NAME, DEFAULT_PROVSRVR_NAME);
         activeProvName = getString(map, Parameters.PROV_ACTIVE_NAME, provName);
-        researchSubnet = getString(map, Parameters.PROV_SPECIAL_SUBNET, RESEARCH_SUBNET);
-        staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
-            ""); //Adding new param for static Routing - Rally:US664862-1610
         initialActivePod = getString(map, Parameters.ACTIVE_POD, "");
         initialStandbyPod = getString(map, Parameters.STANDBY_POD, "");
         staticRoutingNodes = getString(map, Parameters.STATIC_ROUTING_NODES,
-            ""); //Adding new param for static Routing - Rally:US664862-1610
+                ""); //Adding new param for static Routing - Rally:US664862-1610
         activeFeeds = Feed.countActiveFeeds();
         activeSubs = Subscription.countActiveSubscriptions();
         try {
             thisPod = InetAddress.getLocalHost().getHostName();
         } catch (UnknownHostException e) {
             thisPod = "";
-            intlogger.warn("PROV0014 Cannot determine the name of this provisioning server.");
+            intlogger.warn("PROV0014 Cannot determine the name of this provisioning server.", e);
         }
 
         // Normalize the nodes, and fill in nodeAddresses
         InetAddress[] na = new InetAddress[nodes.length];
         for (int i = 0; i < nodes.length; i++) {
-            if (nodes[i].indexOf('.') < 0) {
-                nodes[i] += "." + provDomain;
-            }
             try {
                 na[i] = InetAddress.getByName(nodes[i]);
                 intlogger.debug("PROV0003 DNS lookup: " + nodes[i] + " => " + na[i].toString());
             } catch (UnknownHostException e) {
                 na[i] = null;
-                intlogger.warn("PROV0004 Cannot lookup " + nodes[i] + ": " + e);
+                intlogger.warn("PROV0004 Cannot lookup " + nodes[i] + ": " + e.getMessage(), e);
             }
         }
 
+        //[DATARTR-27] Poke all the DR nodes: assigning DR Nodes
+        drnodes = nodes.clone();
+
         //Reset Nodes arr after - removing static routing Nodes, Rally Userstory - US664862 .
         List<String> filterNodes = new ArrayList<>();
         for (String node : nodes) {
@@ -511,7 +569,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                 filterNodes.add(node);
             }
         }
-        nodes = filterNodes.toArray(new String[filterNodes.size()]);
+        nodes = filterNodes.toArray(new String[0]);
 
         nodeAddresses = na;
         NodeClass.setNodes(nodes);        // update NODES table
@@ -520,15 +578,12 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         String[] pods = getPods();
         na = new InetAddress[pods.length];
         for (int i = 0; i < pods.length; i++) {
-            if (pods[i].indexOf('.') < 0) {
-                pods[i] += "." + provDomain;
-            }
             try {
                 na[i] = InetAddress.getByName(pods[i]);
                 intlogger.debug("PROV0003 DNS lookup: " + pods[i] + " => " + na[i].toString());
             } catch (UnknownHostException e) {
                 na[i] = null;
-                intlogger.warn("PROV0004 Cannot lookup " + pods[i] + ": " + e);
+                intlogger.warn("PROV0004 Cannot lookup " + pods[i] + ": " + e.getMessage(), e);
             }
         }
         podAddresses = na;
@@ -551,42 +606,15 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     private void loadMailProperties() {
         if (mailprops == null) {
             mailprops = new Properties();
-            InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE);
-            try {
+            try (InputStream inStream = getClass().getClassLoader().getResourceAsStream(MAILCONFIG_FILE)) {
                 mailprops.load(inStream);
             } catch (IOException e) {
-                intlogger.fatal("PROV9003 Opening properties: " + e.getMessage());
-                e.printStackTrace();
+                intlogger.error("PROV9003 Opening properties: " + e.getMessage(), e);
                 System.exit(1);
-            } finally {
-                try {
-                    inStream.close();
-                } catch (IOException e) {
-                }
             }
         }
     }
 
-    /**
-     * Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047. Check if HTTPS Relexaction is enabled
-     *
-     * @author vs215k
-     **/
-    private void checkHttpsRelaxation() {
-        if (!mailSendFlag) {
-            Properties p = (new DB()).getProperties();
-            intlogger.info("HTTPS relaxatio: " + p.get("org.onap.dmaap.datarouter.provserver.https.relaxation"));
-
-            if (p.get("org.onap.dmaap.datarouter.provserver.https.relaxation").equals("true")) {
-                try {
-                    notifyPSTeam(p.get("org.onap.dmaap.datarouter.provserver.https.relax.notify").toString());
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-            mailSendFlag = true;
-        }
-    }
 
     /**
      * Data Router Subscriber HTTPS Relaxation feature USERSTORYID:US674047.
@@ -594,7 +622,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
      * @param email - list of email ids to notify if HTTP relexcation is enabled.
      * @author vs215k
      **/
-    private void notifyPSTeam(String email) throws Exception {
+    private void notifyPSTeam(String email) {
         loadMailProperties(); //Load HTTPS Relex mail properties.
         String[] emails = email.split(Pattern.quote("|"));
 
@@ -619,23 +647,30 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             msg.addRecipients(Message.RecipientType.TO, addressTo);
             msg.setSubject(mailprops.get("com.att.dmaap.datarouter.mail.subject").toString());
             htmlPart.setContent(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
-                .replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");
+                    .replace("[SERVER]", InetAddress.getLocalHost().getHostName()), "text/html");
             mp.addBodyPart(htmlPart);
             msg.setContent(mp);
 
-            System.out.println(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
-                .replace("[SERVER]", InetAddress.getLocalHost().getHostName()));
+            intlogger.info(mailprops.get("com.att.dmaap.datarouter.mail.body").toString()
+                    .replace("[SERVER]", InetAddress.getLocalHost().getHostName()));
 
             Transport.send(msg);
             intlogger.info("HTTPS relaxation mail is sent to - : " + email);
 
-        } catch (AddressException e) {
-            intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email);
         } catch (MessagingException e) {
-            intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email);
+            intlogger.error("Invalid email address, unable to send https relaxation mail to - : " + email, e);
+        } catch (UnknownHostException uhe) {
+            intlogger.error("UnknownHostException", uhe);
         }
     }
 
+    public static String getProvName() {
+        return provName;
+    }
+
+    public static String getActiveProvName() {
+        return activeProvName;
+    }
 
     /**
      * Get an array of all node names in the DR network.
@@ -646,6 +681,16 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
         return nodes;
     }
 
+    /**
+     * [DATARTR-27] Poke all the DR nodes
+     * Get an array of all node names in the DR network.
+     *
+     * @return an array of Strings
+     */
+    public static String[] getDRNodes() {
+        return drnodes;
+    }
+
     /**
      * Get an array of all node InetAddresses in the DR network.
      *
@@ -710,8 +755,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             rv = bean.doInsert(conn);
         } catch (SQLException e) {
             rv = false;
-            intlogger.warn("PROV0005 doInsert: " + e.getMessage());
-            e.printStackTrace();
+            intlogger.warn("PROV0005 doInsert: " + e.getMessage(), e);
         } finally {
             if (conn != null) {
                 db.release(conn);
@@ -735,8 +779,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             rv = bean.doUpdate(conn);
         } catch (SQLException e) {
             rv = false;
-            intlogger.warn("PROV0006 doUpdate: " + e.getMessage());
-            e.printStackTrace();
+            intlogger.warn("PROV0006 doUpdate: " + e.getMessage(), e);
         } finally {
             if (conn != null) {
                 db.release(conn);
@@ -760,8 +803,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
             rv = bean.doDelete(conn);
         } catch (SQLException e) {
             rv = false;
-            intlogger.warn("PROV0007 doDelete: " + e.getMessage());
-            e.printStackTrace();
+            intlogger.warn("PROV0007 doDelete: " + e.getMessage(), e);
         } finally {
             if (conn != null) {
                 db.release(conn);
@@ -772,7 +814,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
 
     private static boolean getBoolean(Map<String, String> map, String name) {
         String s = map.get(name);
-        return (s != null) && s.equalsIgnoreCase("true");
+        return (s != null) && "true".equalsIgnoreCase(s);
     }
 
     private static String getString(Map<String, String> map, String name, String dflt) {
@@ -790,7 +832,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     }
 
     private static Set<String> getSet(Map<String, String> map, String name) {
-        Set<String> set = new HashSet<String>();
+        Set<String> set = new HashSet<>();
         String s = map.get(name);
         if (s != null) {
             String[] pp = s.split("\\|");
@@ -813,7 +855,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     public class ContentHeader {
 
         private String type = "";
-        private Map<String, String> map = new HashMap<String, String>();
+        private Map<String, String> map = new HashMap<>();
 
         ContentHeader() {
             this("", "1.0");
@@ -924,7 +966,7 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
                     return true;
                 }
             } catch (JSONException e) {
-                e.printStackTrace();
+                intlogger.error("JSONException: " + e.getMessage(), e);
             }
         }
         return false;
@@ -984,18 +1026,128 @@ public class BaseServlet extends HttpServlet implements ProvDataProvider {
     }
 
     /*
-     * @Method - setIpAndFqdnForEelf - Rally:US664892
+     * @Method - setIpFqdnRequestIDandInvocationIDForEelf
+     * @Params - method, prints method name in EELF log.
+     * @Params- Req, Request used to get RequestId and InvocationId
+     */
+    void setIpFqdnRequestIDandInvocationIDForEelf(String method, HttpServletRequest req) {
+        setIpFqdnForEelf(method);
+        setMDC(req, "X-ONAP-RequestID", MDC_KEY_REQUEST_ID);
+        setMDC(req, "X-InvocationID", "InvocationId");
+    }
+
+    private void setMDC(HttpServletRequest req, String headerName, String keyName) {
+        String mdcId = req.getHeader(headerName);
+        if (StringUtils.isBlank(mdcId)) {
+            mdcId = UUID.randomUUID().toString();
+        }
+        MDC.put(keyName, mdcId);
+    }
+
+    /*
+     * @Method - setIpFqdnRequestIdForEelf - Rally:US664892
      * @Params - method, prints method name in EELF log.
      */
-    void setIpAndFqdnForEelf(String method) {
+    void setIpFqdnForEelf(String method) {
         MDC.clear();
         MDC.put(MDC_SERVICE_NAME, method);
         try {
             MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
             MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
         } catch (Exception e) {
-            e.printStackTrace();
+            intlogger.error("Exception: " + e.getMessage(), e);
+        }
+
+    }
+
+    /*
+     * AAF changes: TDP EPIC US# 307413
+     * @Method - getFeedPermission - Forming permission string for feed part to check AAF access in CADI Framework
+     * @Params - aafInstance Passing aafInstance as it's used in permission string
+     * @Params - userAction Passing CONST values to set different actions in permission string
+     */
+    String getFeedPermission(String aafInstance, String userAction) {
+        try {
+            Properties props = (new DB()).getProperties();
+            String type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+            String action;
+            switch (userAction) {
+                case CREATE_PERMISSION:
+                    action = CREATE_PERMISSION;
+                    break;
+                case EDIT_PERMISSION:
+                    action = EDIT_PERMISSION;
+                    break;
+                case DELETE_PERMISSION:
+                    action = DELETE_PERMISSION;
+                    break;
+                case PUBLISH_PERMISSION:
+                    action = PUBLISH_PERMISSION;
+                    break;
+                case SUSPEND_PERMISSION:
+                    action = SUSPEND_PERMISSION;
+                    break;
+                case RESTORE_PERMISSION:
+                    action = RESTORE_PERMISSION;
+                    break;
+                default:
+                    action = "*";
+            }
+            if (aafInstance == null || "".equals(aafInstance)) {
+                aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
+            }
+            return type + "|" + aafInstance + "|" + action;
+        } catch (Exception e) {
+            intlogger.error("PROV7005 BaseServlet.getFeedPermission: " + e.getMessage(), e);
         }
+        return null;
+    }
 
+    /*
+     * AAF changes: TDP EPIC US# 307413
+     * @Method - getSubscriberPermission - Forming permission string for subscription part to check AAF access in CADI Framework
+     * @Params - aafInstance Passing aafInstance as it's used in permission string
+     * @Params - userAction Passing CONST values to set different actions in permission string
+     */
+    String getSubscriberPermission(String aafInstance, String userAction) {
+        try {
+            Properties props = (new DB()).getProperties();
+            String type = props.getProperty(AAF_CADI_SUB_TYPE, AAF_CADI_SUB);
+            String action;
+            switch (userAction) {
+                case SUBSCRIBE_PERMISSION:
+                    action = SUBSCRIBE_PERMISSION;
+                    type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+                    break;
+                case EDIT_PERMISSION:
+                    action = EDIT_PERMISSION;
+                    break;
+                case DELETE_PERMISSION:
+                    action = DELETE_PERMISSION;
+                    break;
+                case RESTORE_PERMISSION:
+                    action = RESTORE_PERMISSION;
+                    break;
+                case SUSPEND_PERMISSION:
+                    action = SUSPEND_PERMISSION;
+                    break;
+                case PUBLISH_PERMISSION:
+                    action = PUBLISH_PERMISSION;
+                    break;
+                case APPROVE_SUB_PERMISSION:
+                    action = APPROVE_SUB_PERMISSION;
+                    type = props.getProperty(AAF_CADI_FEED_TYPE, AAF_CADI_FEED);
+                    break;
+                default:
+                    action = "*";
+            }
+            if (aafInstance == null || "".equals(aafInstance)) {
+                aafInstance = props.getProperty(AAF_INSTANCE, "org.onap.dmaap-dr.NoInstanceDefined");
+            }
+            return type + "|" + aafInstance + "|" + action;
+        } catch (Exception e) {
+            intlogger.error("PROV7005 BaseServlet.getSubscriberPermission: " + e.getMessage(), e);
+        }
+        return null;
     }
 }