Fixes for sonar critical issues

Fixes for critical and blocker issues reported in sonar.

Issue-Id: POLICY-113
Change-Id: I50969fe93a94b0497f3fb30864a6c45e63208fe6
Signed-off-by: Tej, Tarun <tt3868@att.com>
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java
index cee07fd..7ac322e 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/PapUrlResolver.java
@@ -26,6 +26,7 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Properties;
 
 import org.onap.policy.common.logging.flexlogger.FlexLogger;
@@ -35,343 +36,371 @@
 import com.att.research.xacml.util.XACMLProperties;
 
 public class PapUrlResolver {
-	private static final Logger LOGGER = FlexLogger.getLogger(PapUrlResolver.class);
-	//how long to keep a pap failed before making it un-failed, in milli-seconds
-	private static final long FAIL_TIMEOUT = 18000000;
-	
-	//thread locks
-	public static final Object propertyLock = new Object();
-	
-	//keeping this here for backward compatibility
-	public static String extractIdFromUrl(String url){
-		return extractQuery(url);
-	}
-	public static String extractQuery(String url){
-		try{
-			return URI.create(url).getQuery();
-		} catch(Exception e){
-			LOGGER.error("Exception occured while extracting query. So, empty string is returned"+e);
-			return "";
-		}
-	}
-	public static String modifyUrl(String idUrl, String serverUrl){
-		URI one = URI.create(idUrl);
-		String host = one.getPath()+one.getQuery();
-		URI two = URI.create(serverUrl);
-		two.resolve(host);
-		return two.toString();
-	}
+    private static final Logger LOGGER = FlexLogger.getLogger(PapUrlResolver.class);
+    // how long to keep a pap failed before making it un-failed, in milli-seconds
+    private static final long FAIL_TIMEOUT = 18000000;
 
-	//get an instance of a new PapUrlResolver, using XACMLProperties to get the url lists
-	public static PapUrlResolver getInstance(){
-		return new PapUrlResolver(null,null,null,true);
-	}
-	
-	//get an instance of a new PapUrlResolver, using the provides strings for the url lists
-	public static PapUrlResolver getInstance(String urlList, String failedList, String succeededList){
-		return new PapUrlResolver(urlList, failedList, succeededList,false);
-	}
+    // thread locks
+    public static final Object propertyLock = new Object();
 
-	//keeps track of our current location in the list of urls, allows for iterating
-	private int pointer;
-	
-	//should the XACML property lists be updated after anything changes or should we wait for the update
-	//method to be called.
-	private boolean autoUpdateProperties;
-	
-	//this list keeps the sorted, priority of PAP URLs
-	private PapUrlNode[] sortedUrlNodes;
-	//this list keeps the original list of nodes so that they can be entered into the property list correctly
-	private PapUrlNode[] originalUrlNodes;
-	
-	//private constructor to make an instance of a PapUrlResolver, called by static method getInstance.
-	//If the list property strings are not defined, we get the values from XACMLProperties.
-	//The instance acts as an iterator, with hasNext and next methods, but does not implement Iterable,
-	//because it is used for a difference purpose.
-	private PapUrlResolver(String urlList, String failedList, String succeededList, boolean autoUpdateProperties){	
-		this.autoUpdateProperties = autoUpdateProperties;
-		String papUrlLists = urlList;
-		String papUrlFailedList = failedList;
-		String papUrlSuccessList = succeededList;
-		if(papUrlLists == null){
-			papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS);
-			if(papUrlLists == null){
-				papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
-			}
-			papUrlFailedList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS);
-			papUrlSuccessList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS);
-		}
-		
-		String[] urls = papUrlLists.split(",");
-		if(urls.length == 0){		
-			//log error
-		}
-		String[] failed = emptyOrSplit(papUrlFailedList,urls.length);
-		String[] succeeded = emptyOrSplit(papUrlSuccessList,urls.length);
-		
-		sortedUrlNodes = new PapUrlNode[urls.length];
-		for(int i=0;i<urls.length;i++){
-		
-			String userId = null;
-			String pass = null;
-			userId = XACMLProperties.getProperty(urls[i]+"."+XACMLRestProperties.PROP_PAP_USERID);					
-			pass = XACMLProperties.getProperty(urls[i]+"."+XACMLRestProperties.PROP_PAP_PASS);
-			if(userId == null || pass == null){
-				userId = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
-				pass = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
-			}
-			if(userId == null || pass == null){
-				userId = "";
-				pass = "";
-			}
-			PapUrlNode newNode = new PapUrlNode(urls[i],userId,pass);
-			newNode.setFailedTime(failed[i]);
-			newNode.setSucceededTime(succeeded[i]);
-			if(sortedUrlNodes[i] == null){
-				sortedUrlNodes[i] = newNode;
-			}
-		}
-		originalUrlNodes = sortedUrlNodes.clone();
-		sort(sortedUrlNodes);
-		pointer = 0;
-	}
-	
-	
-	//either split a list by commas, or fill an array to the expected length, if the property list is not long enough
-	private String[] emptyOrSplit(String list,int expectedLength){
-		String[] ret;
-		if(list == null){
-			ret = new String[expectedLength];
-			for(int i=0;i<expectedLength;i++){
-				ret[i] = "-1";
-			}
-		} else {
-			ret = list.split(",");
-			if(ret.length != expectedLength){
-				ret = emptyOrSplit(null,expectedLength);
-			}
-		}
-		return ret;
-	}
-	
-	private void sort(PapUrlNode[] array){
-		
-		//O(n^2) double-loop most likely the best in this case, since number of records will be VERY small
-		for(int i=0;i<array.length;i++){
-			for(int j=i;j<array.length;j++){
-				if(array[j].compareTo(array[i])<0){
-					PapUrlNode temp = array[i];
-					array[i] = array[j];
-					array[j] = temp;
-				}
-			}
-		}
-	}
-	
-	//returns whether this PapUrlResolver object has more PAP urls that can be tried
-	public boolean hasMoreUrls(){
-		return pointer < sortedUrlNodes.length;
-	}
-	
-	//sets the current PAP url as being failed
-	//this will set the failed time to now and remove any succeeded time
-	public void failed(){
-		LOGGER.error("PAP Server FAILED: "+sortedUrlNodes[pointer].getUrl());
+    // keeping this here for backward compatibility
+    public static String extractIdFromUrl(String url) {
+        return extractQuery(url);
+    }
 
-		sortedUrlNodes[pointer].setFailedTime(new Date());
-		sortedUrlNodes[pointer].setSucceededTime(null);
-		propertiesUpdated();
-	}
-	
-	//sets the current PAP url as being working
-	//this will set the succeeded time to now and remove any failed time
-	//Also, this will cause hasMoreUrls to return false, since a working one has been found
-	
-	public void succeeded(){
-		registered();
-		pointer = sortedUrlNodes.length;
-	}
-	public void registered(){
-		sortedUrlNodes[pointer].setFailedTime(null);
-		sortedUrlNodes[pointer].setSucceededTime(new Date());
-		LOGGER.info("PAP server SUCCEEDED "+sortedUrlNodes[pointer].getUrl());
-		propertiesUpdated();
-	}
-	
-	//returns a properties object with the properties that pertain to PAP urls
-	public Properties getProperties(){
-		String failedPropertyString = "";
-		String succeededPropertyString = "";
-		String urlPropertyString = "";
-		for(int i=0;i<originalUrlNodes.length;i++){
-			failedPropertyString = failedPropertyString.concat(",").concat(originalUrlNodes[i].getFailedTime());
-			succeededPropertyString = succeededPropertyString.concat(",").concat(originalUrlNodes[i].getSucceededTime());
-			urlPropertyString = urlPropertyString.concat(",").concat(originalUrlNodes[i].getUrl());
-		}
-		Properties prop = new Properties();
-		failedPropertyString = failedPropertyString.substring(1);
-		succeededPropertyString = succeededPropertyString.substring(1);
-		urlPropertyString = urlPropertyString.substring(1);
-		prop.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS,failedPropertyString);
-		prop.setProperty(XACMLRestProperties.PROP_PAP_URLS,urlPropertyString);
-		prop.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS,succeededPropertyString);
-		return prop;
-	}
-	
-	//saves the updates urls to the correct properties
-	private void propertiesUpdated(){
-		if(!autoUpdateProperties){
-			return;
-		}
-		Properties prop = getProperties();
+    public static String extractQuery(String url) {
+        try {
+            return URI.create(url).getQuery();
+        } catch (Exception e) {
+            LOGGER.error("Exception occured while extracting query. So, empty string is returned" + e);
+            return "";
+        }
+    }
 
-		LOGGER.debug("Failed PAP Url List: "+prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
-		LOGGER.debug("Succeeded PAP Url List: "+prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
-		XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS,prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
-		XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS,prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
-	}
-	
-	//iterates to the next available PAP url, according to the priority order
-	public void getNext(){
-		pointer++;
-	}
-	
-	//returns the url of the current PAP server that we are iterating over
-	//will append the provided policy id to the url
-	public String getUrl(String query){
-		if(sortedUrlNodes[pointer]== null){
-			throw new NoSuchElementException();
-		} else {
-			return sortedUrlNodes[pointer].getUrl().concat("?").concat(query);
-		}
-	}
-	
-	//returns the url of the current PAP server that we are iterating over
-	//Just returns the url, with no id appended to it
-	public String getUrl(){
-		if(sortedUrlNodes[pointer]== null){
-			throw new NoSuchElementException();
-		} else {	
-			
-			return sortedUrlNodes[pointer].getUrl();
-		}
-	}
-	public String getUserId(){
-		if(sortedUrlNodes[pointer]== null){
-			throw new NoSuchElementException();
-		} else {	
-			
-			return sortedUrlNodes[pointer].getUserId();
-		}
-	}
-	public String getPass(){
-		if(sortedUrlNodes[pointer]== null){
-			throw new NoSuchElementException();
-		} else {	
-			
-			return sortedUrlNodes[pointer].getPass();
-		}
-	}
+    public static String modifyUrl(String idUrl, String serverUrl) {
+        URI one = URI.create(idUrl);
+        String host = one.getPath() + one.getQuery();
+        URI two = URI.create(serverUrl);
+        two.resolve(host);
+        return two.toString();
+    }
 
-	
-	//This is the class to hold the details of a single PAP URL
-	//including: the url itself, the last time it failed, and the last time it succeeded
-	//It also includes the custom comparer which can compare based on failed and succeeded times, and takes into account
-	//the timeout on failures.
-	private class PapUrlNode implements Comparable<PapUrlNode> {
-		private String papUrl;
-		private Date failedTime;
-		private Date succeededTime;
-		private String userId;
-		private String pass;
-		
-		public PapUrlNode(String url,String userId,String pass){
-			this.papUrl = url;
-			failedTime = null;
-			this.succeededTime = null;
-			this.userId = userId;
-			this.pass = pass;
-			
-		}
-		public String getUserId(){
-			return this.userId;
-		}
-		public String getPass(){
-			return this.pass;
-		}
-		
-		public void setFailedTime(Object time){
-			Date failedTimeAsDate = setHandler(time);
-			if(failedTimeAsDate == null){
-				this.failedTime = null;
-			} else {
-				long timeDifference = new Date().getTime() - failedTimeAsDate.getTime();
-				if(timeDifference < FAIL_TIMEOUT){
-					this.failedTime = failedTimeAsDate;
-				} else {
-					this.failedTime = null;
-				}
-			}
-		}
-		
-		//set the time that this url succeeded at
-		public void setSucceededTime(Object time){
-			this.succeededTime = setHandler(time);
-		}
-		
-		//parses string into a date or a null date, if the url never failed/succeeded (since -1 will be in the property)
-		private Date setHandler(Object time){
-			if(time instanceof String){
-				if("-1".equals((String)time)){
-					return null;
-				}
-				try {
-					DateFormat df = new SimpleDateFormat();
-					return df.parse((String)time);
-				} catch (ParseException e) {					
-					return null;
-				}
-			}
-			if(time instanceof Date){
-				return (Date)time;
-			}
-			return null;
-		}
-		
-		
-		public String getFailedTime(){
-			return formatTime(this.failedTime);
-		}
-		
-		public String getSucceededTime(){
-			return formatTime(this.succeededTime);
-		}
-		
-		//formats a Date into a string or a -1 if there is not date (-1 is used in properties for no date)
-		private String formatTime(Date d){
-			if(d == null){
-				return "-1";
-			}
-			DateFormat df = new SimpleDateFormat();
-			return df.format(d);
-		}
-		
-		public String getUrl(){
-			return papUrl;
-		}
-		
-		@Override
-		public int compareTo(PapUrlNode other){
-			if(this.failedTime == null && other.failedTime != null){
-				return -1;
-			}
-			if(this.failedTime != null && other.failedTime == null){
-				return 1;
-			}
-			if(this.failedTime != null){
-				return this.failedTime.compareTo(other.failedTime);
-			}
-			return 0;
-		}
-	}
+    // get an instance of a new PapUrlResolver, using XACMLProperties to get the url lists
+    public static PapUrlResolver getInstance() {
+        return new PapUrlResolver(null, null, null, true);
+    }
+
+    // get an instance of a new PapUrlResolver, using the provides strings for the url lists
+    public static PapUrlResolver getInstance(String urlList, String failedList, String succeededList) {
+        return new PapUrlResolver(urlList, failedList, succeededList, false);
+    }
+
+    // keeps track of our current location in the list of urls, allows for iterating
+    private int pointer;
+
+    // should the XACML property lists be updated after anything changes or should we wait for the update
+    // method to be called.
+    private boolean autoUpdateProperties;
+
+    // this list keeps the sorted, priority of PAP URLs
+    private PapUrlNode[] sortedUrlNodes;
+    // this list keeps the original list of nodes so that they can be entered into the property list correctly
+    private PapUrlNode[] originalUrlNodes;
+
+    // private constructor to make an instance of a PapUrlResolver, called by static method getInstance.
+    // If the list property strings are not defined, we get the values from XACMLProperties.
+    // The instance acts as an iterator, with hasNext and next methods, but does not implement Iterable,
+    // because it is used for a difference purpose.
+    private PapUrlResolver(String urlList, String failedList, String succeededList, boolean autoUpdateProperties) {
+        this.autoUpdateProperties = autoUpdateProperties;
+        String papUrlLists = urlList;
+        String papUrlFailedList = failedList;
+        String papUrlSuccessList = succeededList;
+        if (papUrlLists == null) {
+            papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS);
+            if (papUrlLists == null) {
+                papUrlLists = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
+            }
+            papUrlFailedList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS);
+            papUrlSuccessList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS);
+        }
+
+        String[] urls = papUrlLists.split(",");
+        if (urls.length == 0) {
+            // log error
+        }
+        String[] failed = emptyOrSplit(papUrlFailedList, urls.length);
+        String[] succeeded = emptyOrSplit(papUrlSuccessList, urls.length);
+
+        sortedUrlNodes = new PapUrlNode[urls.length];
+        for (int i = 0; i < urls.length; i++) {
+
+            String userId = null;
+            String pass = null;
+            userId = XACMLProperties.getProperty(urls[i] + "." + XACMLRestProperties.PROP_PAP_USERID);
+            pass = XACMLProperties.getProperty(urls[i] + "." + XACMLRestProperties.PROP_PAP_PASS);
+            if (userId == null || pass == null) {
+                userId = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
+                pass = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
+            }
+            if (userId == null || pass == null) {
+                userId = "";
+                pass = "";
+            }
+            PapUrlNode newNode = new PapUrlNode(urls[i], userId, pass);
+            newNode.setFailedTime(failed[i]);
+            newNode.setSucceededTime(succeeded[i]);
+            if (sortedUrlNodes[i] == null) {
+                sortedUrlNodes[i] = newNode;
+            }
+        }
+        originalUrlNodes = sortedUrlNodes.clone();
+        sort(sortedUrlNodes);
+        pointer = 0;
+    }
+
+    // either split a list by commas, or fill an array to the expected length, if the property list is not long enough
+    private String[] emptyOrSplit(String list, int expectedLength) {
+        String[] ret;
+        if (list == null) {
+            ret = new String[expectedLength];
+            for (int i = 0; i < expectedLength; i++) {
+                ret[i] = "-1";
+            }
+        } else {
+            ret = list.split(",");
+            if (ret.length != expectedLength) {
+                ret = emptyOrSplit(null, expectedLength);
+            }
+        }
+        return ret;
+    }
+
+    private void sort(PapUrlNode[] array) {
+
+        // O(n^2) double-loop most likely the best in this case, since number of records will be VERY small
+        for (int i = 0; i < array.length; i++) {
+            for (int j = i; j < array.length; j++) {
+                if (array[j].compareTo(array[i]) < 0) {
+                    PapUrlNode temp = array[i];
+                    array[i] = array[j];
+                    array[j] = temp;
+                }
+            }
+        }
+    }
+
+    // returns whether this PapUrlResolver object has more PAP urls that can be tried
+    public boolean hasMoreUrls() {
+        return pointer < sortedUrlNodes.length;
+    }
+
+    // sets the current PAP url as being failed
+    // this will set the failed time to now and remove any succeeded time
+    public void failed() {
+        LOGGER.error("PAP Server FAILED: " + sortedUrlNodes[pointer].getUrl());
+
+        sortedUrlNodes[pointer].setFailedTime(new Date());
+        sortedUrlNodes[pointer].setSucceededTime(null);
+        propertiesUpdated();
+    }
+
+    // sets the current PAP url as being working
+    // this will set the succeeded time to now and remove any failed time
+    // Also, this will cause hasMoreUrls to return false, since a working one has been found
+
+    public void succeeded() {
+        registered();
+        pointer = sortedUrlNodes.length;
+    }
+
+    public void registered() {
+        sortedUrlNodes[pointer].setFailedTime(null);
+        sortedUrlNodes[pointer].setSucceededTime(new Date());
+        LOGGER.info("PAP server SUCCEEDED " + sortedUrlNodes[pointer].getUrl());
+        propertiesUpdated();
+    }
+
+    // returns a properties object with the properties that pertain to PAP urls
+    public Properties getProperties() {
+        String failedPropertyString = "";
+        String succeededPropertyString = "";
+        String urlPropertyString = "";
+        for (int i = 0; i < originalUrlNodes.length; i++) {
+            failedPropertyString = failedPropertyString.concat(",").concat(originalUrlNodes[i].getFailedTime());
+            succeededPropertyString = succeededPropertyString.concat(",")
+                    .concat(originalUrlNodes[i].getSucceededTime());
+            urlPropertyString = urlPropertyString.concat(",").concat(originalUrlNodes[i].getUrl());
+        }
+        Properties prop = new Properties();
+        failedPropertyString = failedPropertyString.substring(1);
+        succeededPropertyString = succeededPropertyString.substring(1);
+        urlPropertyString = urlPropertyString.substring(1);
+        prop.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS, failedPropertyString);
+        prop.setProperty(XACMLRestProperties.PROP_PAP_URLS, urlPropertyString);
+        prop.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS, succeededPropertyString);
+        return prop;
+    }
+
+    // saves the updates urls to the correct properties
+    private void propertiesUpdated() {
+        if (!autoUpdateProperties) {
+            return;
+        }
+        Properties prop = getProperties();
+
+        LOGGER.debug("Failed PAP Url List: " + prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
+        LOGGER.debug("Succeeded PAP Url List: " + prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
+        XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS,
+                prop.getProperty(XACMLRestProperties.PROP_PAP_FAILED_URLS));
+        XACMLProperties.setProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS,
+                prop.getProperty(XACMLRestProperties.PROP_PAP_SUCCEEDED_URLS));
+    }
+
+    // iterates to the next available PAP url, according to the priority order
+    public void getNext() {
+        pointer++;
+    }
+
+    // returns the url of the current PAP server that we are iterating over
+    // will append the provided policy id to the url
+    public String getUrl(String query) {
+        if (sortedUrlNodes[pointer] == null) {
+            throw new NoSuchElementException();
+        } else {
+            return sortedUrlNodes[pointer].getUrl().concat("?").concat(query);
+        }
+    }
+
+    // returns the url of the current PAP server that we are iterating over
+    // Just returns the url, with no id appended to it
+    public String getUrl() {
+        if (sortedUrlNodes[pointer] == null) {
+            throw new NoSuchElementException();
+        } else {
+
+            return sortedUrlNodes[pointer].getUrl();
+        }
+    }
+
+    public String getUserId() {
+        if (sortedUrlNodes[pointer] == null) {
+            throw new NoSuchElementException();
+        } else {
+
+            return sortedUrlNodes[pointer].getUserId();
+        }
+    }
+
+    public String getPass() {
+        if (sortedUrlNodes[pointer] == null) {
+            throw new NoSuchElementException();
+        } else {
+
+            return sortedUrlNodes[pointer].getPass();
+        }
+    }
+
+    // This is the class to hold the details of a single PAP URL
+    // including: the url itself, the last time it failed, and the last time it succeeded
+    // It also includes the custom comparer which can compare based on failed and succeeded times, and takes into
+    // account
+    // the timeout on failures.
+    private class PapUrlNode implements Comparable<PapUrlNode> {
+        private String papUrl;
+        private Date failedTime;
+        private Date succeededTime;
+        private String userId;
+        private String pass;
+
+        public PapUrlNode(String url, String userId, String pass) {
+            this.papUrl = url;
+            failedTime = null;
+            this.succeededTime = null;
+            this.userId = userId;
+            this.pass = pass;
+
+        }
+
+        public String getUserId() {
+            return this.userId;
+        }
+
+        public String getPass() {
+            return this.pass;
+        }
+
+        public void setFailedTime(Object time) {
+            Date failedTimeAsDate = setHandler(time);
+            if (failedTimeAsDate == null) {
+                this.failedTime = null;
+            } else {
+                long timeDifference = new Date().getTime() - failedTimeAsDate.getTime();
+                if (timeDifference < FAIL_TIMEOUT) {
+                    this.failedTime = failedTimeAsDate;
+                } else {
+                    this.failedTime = null;
+                }
+            }
+        }
+
+        // set the time that this url succeeded at
+        public void setSucceededTime(Object time) {
+            this.succeededTime = setHandler(time);
+        }
+
+        // parses string into a date or a null date, if the url never failed/succeeded (since -1 will be in the
+        // property)
+        private Date setHandler(Object time) {
+            if (time instanceof String) {
+                if ("-1".equals((String) time)) {
+                    return null;
+                }
+                try {
+                    DateFormat df = new SimpleDateFormat();
+                    return df.parse((String) time);
+                } catch (ParseException e) {
+                    return null;
+                }
+            }
+            if (time instanceof Date) {
+                return (Date) time;
+            }
+            return null;
+        }
+
+        public String getFailedTime() {
+            return formatTime(this.failedTime);
+        }
+
+        public String getSucceededTime() {
+            return formatTime(this.succeededTime);
+        }
+
+        // formats a Date into a string or a -1 if there is not date (-1 is used in properties for no date)
+        private String formatTime(Date d) {
+            if (d == null) {
+                return "-1";
+            }
+            DateFormat df = new SimpleDateFormat();
+            return df.format(d);
+        }
+
+        public String getUrl() {
+            return papUrl;
+        }
+
+        @Override
+        public int compareTo(PapUrlNode other) {
+            if (this.failedTime == null && other.failedTime != null) {
+                return -1;
+            }
+            if (this.failedTime != null && other.failedTime == null) {
+                return 1;
+            }
+            if (this.failedTime != null) {
+                return this.failedTime.compareTo(other.failedTime);
+            }
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (!(obj instanceof PapUrlNode)) {
+                return false;
+            }
+            PapUrlNode papUrlNode = (PapUrlNode) obj;
+            return Objects.equals(papUrlNode.papUrl, papUrl) && Objects.equals(papUrlNode.failedTime, failedTime)
+                    && Objects.equals(papUrlNode.succeededTime, succeededTime)
+                    && Objects.equals(papUrlNode.userId, userId) && Objects.equals(papUrlNode.pass, pass);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(papUrl, failedTime, succeededTime, userId, pass);
+        }
+    }
 }
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java
index d57e884..18c2017 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/XACMLPdpServlet.java
@@ -130,8 +130,8 @@
 	// This thread may getting invoked on startup, to let the PAP know
 	// that we are up and running.
 	//
-	private Thread registerThread = null;
-	private XACMLPdpRegisterThread registerRunnable = null;
+	private static transient Thread registerThread = null;
+	private static transient XACMLPdpRegisterThread registerRunnable = null;
 	//
 	// This is our PDP engine pointer. There is a synchronized lock used
 	// for access to the pointer. In case we are servicing PEP requests while
@@ -176,10 +176,10 @@
 	// This is our configuration thread that attempts to load
 	// a new configuration request.
 	//
-	private Thread configThread = null;
-	private volatile boolean configThreadTerminate = false;
-	private ONAPLoggingContext baseLoggingContext = null;
-	private IntegrityMonitor im;
+	private static transient Thread configThread = null;
+	private static volatile boolean configThreadTerminate = false;
+	private transient ONAPLoggingContext baseLoggingContext = null;
+	private transient IntegrityMonitor im;
 	/**
 	 * Default constructor. 
 	 */
@@ -198,16 +198,12 @@
 		// Initialize
 		//
 		XACMLRest.xacmlInit(config);
-		// Load the Notification Delay. 
-		try{
-			XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
-		}catch(Exception e){
-			logger.info("Notification Delay Not set. Keeping it 0 as default."+e);
-		}
+		// Load the Notification Delay.
+		setNotificationDelay();
 		// Load Queue size. 
 		int queueSize = 5; // Set default Queue Size here. 
 		queueSize = Integer.parseInt(XACMLProperties.getProperty("REQUEST_BUFFER_SIZE",String.valueOf(queueSize)));
-		queue = new LinkedBlockingQueue<PutRequest>(queueSize);
+		initQueue(queueSize);
 		// Load our engine - this will use the latest configuration
 		// that was saved to disk and set our initial status object.
 		//
@@ -250,25 +246,14 @@
 			}
 			PolicyLogger.info("\n Properties Given : \n" + properties.toString());
 		}
-		pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
-		if(pdpResourceName == null){
-			PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
-			throw new ServletException("pdpResourceName is null");
-		}
-
+		setPDPResourceName(properties);
 		dependencyGroups = properties.getProperty(IntegrityMonitorProperties.DEPENDENCY_GROUPS);
 		if(dependencyGroups == null){
 			PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, IntegrityMonitorProperties.DEPENDENCY_GROUPS, "xacml.pdp");
 			throw new ServletException("dependency_groups is null");
 		}
-		// dependency_groups is a semicolon-delimited list of groups, and
-		// each group is a comma-separated list of nodes. For our purposes
-		// we just need a list of dependencies without regard to grouping,
-		// so split the list into nodes separated by either comma or semicolon.
-		dependencyNodes = dependencyGroups.split("[;,]");
-		for (int i = 0 ; i < dependencyNodes.length ; i++){
-			dependencyNodes[i] = dependencyNodes[i].trim();
-		}
+		setDependencyNodes(dependencyGroups);
+		
 
 		// CreateUpdatePolicy ResourceName  
 		createUpdateResourceName = properties.getProperty("createUpdatePolicy.impl.className", CREATE_UPDATE_POLICY_SERVICE);
@@ -282,25 +267,59 @@
 			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "Failed to create IntegrityMonitor" +e);
 			throw new ServletException(e);
 		}
-
-		environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
-		//
-		// Kick off our thread to register with the PAP servlet.
-		//
-		if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
-			this.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
-			this.registerThread = new Thread(this.registerRunnable);
-			this.registerThread.start();
-		}
-		//
-		// This is our thread that manages incoming configuration
-		// changes.
-		//
-		this.configThread = new Thread(this);
-		this.configThread.start();
+		startThreads(baseLoggingContext, new Thread(this));
 	}
 
-	/**
+	private static void startThreads(ONAPLoggingContext baseLoggingContext, Thread thread) {
+	    environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
+        //
+        // Kick off our thread to register with the PAP servlet.
+        //
+        if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_REGISTER))) {
+            XACMLPdpServlet.registerRunnable = new XACMLPdpRegisterThread(baseLoggingContext);
+            XACMLPdpServlet.registerThread = new Thread(XACMLPdpServlet.registerRunnable);
+            XACMLPdpServlet.registerThread.start();
+        }
+        //
+        // This is our thread that manages incoming configuration
+        // changes.
+        //
+        XACMLPdpServlet.configThread = thread;
+        XACMLPdpServlet.configThread.start();
+    }
+
+    private static void setDependencyNodes(String dependencyGroups) {
+	    // dependency_groups is a semicolon-delimited list of groups, and
+        // each group is a comma-separated list of nodes. For our purposes
+        // we just need a list of dependencies without regard to grouping,
+        // so split the list into nodes separated by either comma or semicolon.
+        dependencyNodes = dependencyGroups.split("[;,]");
+        for (int i = 0 ; i < dependencyNodes.length ; i++){
+            dependencyNodes[i] = dependencyNodes[i].trim();
+        }
+    }
+
+    private static void setPDPResourceName(Properties properties) throws ServletException {
+	    pdpResourceName = properties.getProperty(XACMLRestProperties.PDP_RESOURCE_NAME);
+        if(pdpResourceName == null){
+            PolicyLogger.error(MessageCodes.MISS_PROPERTY_ERROR, XACMLRestProperties.PDP_RESOURCE_NAME, "xacml.pdp");
+            throw new ServletException("pdpResourceName is null");
+        }
+    }
+
+    private static void initQueue(int queueSize) {
+	    queue = new LinkedBlockingQueue<>(queueSize);
+    }
+
+    private static void setNotificationDelay() {
+        try{
+            XACMLPdpServlet.notificationDelay = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_DELAY));
+        }catch(NumberFormatException e){
+            logger.error("Error in notification delay format, Taking the default value.", e);
+        }
+    }
+
+    /**
 	 * @see Servlet#destroy()
 	 */
 	@Override
@@ -310,33 +329,39 @@
 		//
 		// Make sure the register thread is not running
 		//
-		if (this.registerRunnable != null) {
+		if (XACMLPdpServlet.registerRunnable != null) {
 			try {
-				this.registerRunnable.terminate();
-				if (this.registerThread != null) {
-					this.registerThread.interrupt();
-					this.registerThread.join();
+				XACMLPdpServlet.registerRunnable.terminate();
+				if (XACMLPdpServlet.registerThread != null) {
+					XACMLPdpServlet.registerThread.interrupt();
+					XACMLPdpServlet.registerThread.join();
 				}
 			} catch (InterruptedException e) {
 				logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
 				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
+				XACMLPdpServlet.registerThread.interrupt();
 			}
 		}
 		//
 		// Make sure the configure thread is not running
 		//
-		this.configThreadTerminate = true;
+		setConfigThreadTerminate(true);
 		try {
-			this.configThread.interrupt();
-			this.configThread.join();
+			XACMLPdpServlet.configThread.interrupt();
+			XACMLPdpServlet.configThread.join();
 		} catch (InterruptedException e) {
 			logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
 			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "");
+			XACMLPdpServlet.configThread.interrupt();
 		}
 		logger.info("Destroyed.");
 	}
 
-	/**
+	private static void setConfigThreadTerminate(boolean value) {
+	    XACMLPdpServlet.configThreadTerminate = value;
+    }
+
+    /**
 	 * PUT - The PAP engine sends configuration information using HTTP PUT request.
 	 * 
 	 * One parameter is expected:
@@ -937,7 +962,13 @@
 			// Read in the string
 			//
 			StringBuilder buffer = new StringBuilder();
-			BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
+			BufferedReader reader = null;
+			try{
+			    reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
+			}catch(IOException e){
+			    logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error during reading input stream",e);
+			    return;
+			}
 			String line;
 			try{
 				while((line = reader.readLine()) != null){
@@ -1198,7 +1229,7 @@
 		//
 		try {
 			// variable not used, but constructor has needed side-effects so don't remove:
-			while (! this.configThreadTerminate) {
+			while (! XACMLPdpServlet.configThreadTerminate) {
 				PutRequest request = XACMLPdpServlet.queue.take();
 				StdPDPStatus newStatus = new StdPDPStatus();
 				
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java
index e7216e1..f7c175c 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java
@@ -227,112 +227,96 @@
         String [] parameters = {"apiflag=version","policyScope="+policyScope, "filePrefix="+filePrefix, "policyName="+policyName};
         if (paps == null || paps.isEmpty()) {
             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PAPs List is Empty.");
-            try {
-                throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"PAPs List is empty.");
-            } catch (Exception e) {
-                LOGGER.error(e.getMessage() + e);
-            }
-            }else {
-                int papsCount = 0;
-                boolean connected = false;
-                while (papsCount < paps.size()) {
-                    try {
-                        String fullURL = getPAP();
-                        if (parameters != null && parameters.length > 0) {
-                            String queryString = "";
-                            for (String p : parameters) {
-                                queryString += "&" + p;
-                            }
-                            fullURL += "?" + queryString.substring(1);
+        }else {
+            int papsCount = 0;
+            boolean connected = false;
+            while (papsCount < paps.size()) {
+                try {
+                    String fullURL = getPAP();
+                    if (parameters != null && parameters.length > 0) {
+                        String queryString = "";
+                        for (String p : parameters) {
+                            queryString += "&" + p;
                         }
-        
-                        URL url = new URL (fullURL);
-                        
-                        //Open the connection
-                        connection = (HttpURLConnection)url.openConnection();
-                        
-                        // Setting Content-Type
-                        connection.setRequestProperty("Content-Type",
-                                "application/json");
-                        
-                        // Adding Authorization
-                        connection.setRequestProperty("Authorization", "Basic "
-                                + getPAPEncoding());
-                        
-                        connection.setRequestProperty("Environment", environment);
-                        connection.setRequestProperty("ClientScope", clientScope);
-
-                        
-                        //set the method and headers
-                        connection.setRequestMethod("GET");
-                        connection.setUseCaches(false);
-                        connection.setInstanceFollowRedirects(false);
-                        connection.setDoOutput(true);
-                        connection.setDoInput(true);
-                        connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
-  
-                        //DO the connect
-                        connection.connect();
-        
-                        // If Connected to PAP then break from the loop and continue with the Request 
-                        if (connection.getResponseCode() > 0) {
-                            connected = true;
-                            break;
-
-                        } else {
-                            LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error");
-                        }
-                    } catch (Exception e) {
-                        // This means that the PAP is not working 
-                        LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e);
-                        rotatePAPList();
+                        fullURL += "?" + queryString.substring(1);
                     }
-                    papsCount++;
+
+                    URL url = new URL (fullURL);
+
+                    //Open the connection
+                    connection = (HttpURLConnection)url.openConnection();
+
+                    // Setting Content-Type
+                    connection.setRequestProperty("Content-Type",
+                            "application/json");
+
+                    // Adding Authorization
+                    connection.setRequestProperty("Authorization", "Basic "
+                            + getPAPEncoding());
+
+                    connection.setRequestProperty("Environment", environment);
+                    connection.setRequestProperty("ClientScope", clientScope);
+
+
+                    //set the method and headers
+                    connection.setRequestMethod("GET");
+                    connection.setUseCaches(false);
+                    connection.setInstanceFollowRedirects(false);
+                    connection.setDoOutput(true);
+                    connection.setDoInput(true);
+                    connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
+
+                    //DO the connect
+                    connection.connect();
+
+                    // If Connected to PAP then break from the loop and continue with the Request 
+                    if (connection.getResponseCode() > 0) {
+                        connected = true;
+                        break;
+
+                    } else {
+                        LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error");
+                    }
+                } catch (Exception e) {
+                    // This means that the PAP is not working 
+                    LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e);
+                    rotatePAPList();
                 }
-        
-                if (connected) {
-                    //Read the Response
-                    LOGGER.debug("connected to the PAP : " + getPAP());
-                    LOGGER.debug("--- Response: ---");
-                    Map<String, List<String>> headers = connection.getHeaderFields();
-                    for (String key : headers.keySet()) {
-                        LOGGER.debug("Header :" + key + "  Value: " + headers.get(key));
-                    }
-                    try {
-                        if (connection.getResponseCode() == 200) {
-                            // Check for successful creation of policy
-                            version = connection.getHeaderField("version");
-                            LOGGER.debug("ActiveVersion from the Header: " + version);
-                        } else if (connection.getResponseCode() == 403) {
-                            LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is " 
-                                    + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ");
-                            version = "pe100";
-                        } else if (connection.getResponseCode() == 404) {
-                            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is " 
-                                        + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP");
-                            version = "pe300";
-                        } else {
-                            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST:  Error occured while getting the version from the PAP. The request may be incorrect.");
-                        }
-                    } catch (IOException e) {
-                        LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-                        try {
-                            throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"ERROR in connecting to the PAP ", e);
-                        } catch (Exception e1) {
-                            LOGGER.error(e1.getMessage() + e1);
-                        }
-                    } 
-        
-                } else {
-                    LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps);
-                    try {
-                        throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"ERROR in connecting to the PAP ");
-                    } catch (Exception e) {
-                        LOGGER.error(e.getMessage() + e);
-                    }
-                }   
+                papsCount++;
             }
-            return version;
+
+            if (connected) {
+                //Read the Response
+                LOGGER.debug("connected to the PAP : " + getPAP());
+                LOGGER.debug("--- Response: ---");
+                Map<String, List<String>> headers = connection.getHeaderFields();
+                for (String key : headers.keySet()) {
+                    LOGGER.debug("Header :" + key + "  Value: " + headers.get(key));
+                }
+                try {
+                    if (connection.getResponseCode() == 200) {
+                        // Check for successful creation of policy
+                        version = connection.getHeaderField("version");
+                        LOGGER.debug("ActiveVersion from the Header: " + version);
+                    } else if (connection.getResponseCode() == 403) {
+                        LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is " 
+                                + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ");
+                        version = "pe100";
+                    } else if (connection.getResponseCode() == 404) {
+                        LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is " 
+                                + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP");
+                        version = "pe300";
+                    } else {
+                        LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST:  Error occured while getting the version from the PAP. The request may be incorrect.");
+                    }
+                } catch (IOException e) {
+                    LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
+                } 
+            } else {
+                LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps);
+            }   
+        }
+        return version;
     }
     
     private String checkResponse(HttpURLConnection connection, UUID requestID) throws IOException {
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java
index e495c99..efaa5c1 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PDPServices.java
@@ -21,10 +21,10 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringWriter;
-import java.net.MalformedURLException;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -37,6 +37,7 @@
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
@@ -65,6 +66,7 @@
 import com.att.research.xacml.api.Response;
 import com.att.research.xacml.api.Result;
 import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPException;
 import com.att.research.xacml.std.json.JSONRequest;
 import com.att.research.xacml.std.json.JSONResponse;
 import com.att.research.xacml.util.XACMLProperties;
@@ -333,7 +335,7 @@
     	return treatment;
     }
 
-    private PDPResponse configCall(String pdpConfigLocation) throws Exception{
+    private PDPResponse configCall(String pdpConfigLocation) throws PDPException, IOException{
         PDPResponse pdpResponse = new PDPResponse();
         if(pdpConfigLocation.contains("/")){
             pdpConfigLocation = pdpConfigLocation.replace("/", File.separator);
@@ -366,7 +368,7 @@
                         pdpResponse.setConfig(writer.toString());
                     } catch (Exception e) {
                         LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ e);
-                        throw new Exception(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the XML config", e);
+                        throw new PDPException(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the XML config", e);
                     }
                 } else if (pdpConfigLocation.endsWith("properties")) {
                     pdpResponse.setType(PolicyType.PROPERTIES);
@@ -394,14 +396,14 @@
                         PolicyResponseStatus.NO_ACTION_REQUIRED,
                         PolicyConfigStatus.CONFIG_RETRIEVED);
                 return pdpResponse;
-            } catch (IOException e) {
+            } catch (IOException | ParserConfigurationException e) {
                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
-                throw new Exception(XACMLErrorConstants.ERROR_PROCESS_FLOW +
+                throw new PDPException(XACMLErrorConstants.ERROR_PROCESS_FLOW +
                         "Cannot open a connection to the configURL", e);
             }
-        } catch (MalformedURLException e) {
+        } catch (FileNotFoundException e) {
             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-            throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in ConfigURL", e);
+            throw new PDPException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in ConfigURL", e);
         }finally{
         	if(inputStream != null){
             	inputStream.close();
@@ -409,8 +411,7 @@
         }
     }
 
-    private Response callPDP(Request request,
-            UUID requestID) throws Exception{
+    private Response callPDP(Request request, UUID requestID){
         Response response = null;
         // Get the PDPEngine
         if (requestID == null) {
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
index 2d8af54..d0649d7 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
@@ -62,7 +62,7 @@
                     requestUUID = UUID.fromString(requestID);
                 } catch (IllegalArgumentException e) {
                     requestUUID = UUID.randomUUID();
-                    LOGGER.info("Generated Random UUID: " + requestUUID.toString());
+                    LOGGER.info("Generated Random UUID: " + requestUUID.toString(), e);
                 }
             }else{
                 requestUUID = UUID.randomUUID();
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java
index c130657..9027e27 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/ManualNotificationUpdateThread.java
@@ -44,186 +44,205 @@
 @SuppressWarnings("deprecation")
 public class ManualNotificationUpdateThread implements Runnable {
 
-	private static final Logger LOGGER	= FlexLogger.getLogger(ManualNotificationUpdateThread.class);
+    private static final Logger LOGGER = FlexLogger.getLogger(ManualNotificationUpdateThread.class);
 
-	private static String topic = null;
-	private static CambriaConsumer CConsumer = null;
-	private static String clusterList = null;
-	private static String update = null;
-	private static BusConsumer dmaapConsumer = null;
-	private static List<String> dmaapList = null;
-	private static String propNotificationType = null;
-	private static String aafLogin = null;
-	private static String aafPassword = null;
-	
-	public volatile boolean isRunning = false;
-	
-	public synchronized boolean isRunning() {
-		return this.isRunning;
-	}
-	
-	public synchronized void terminate() {
-		this.isRunning = false;
-	}
-	
-	/**
-	 * 
-	 * This is our thread that runs on startup if the system is configured to UEB to accept manual update requests
-	 * 
-	 */
-	@Override
-	public void run() {
-		synchronized(this) {
-			this.isRunning = true;
-		}
-		
-		URL aURL = null;
-		String group =  UUID.randomUUID ().toString ();
-		String id = "0";
-		String returnTopic = null;
-		propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE);
-		if ("ueb".equals(propNotificationType)){
-			try {
-				clusterList = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS).trim();
-				String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID);
-				aURL = new URL(url);
-				topic = aURL.getHost() + aURL.getPort();
-			} catch (NumberFormatException e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get UEB cluster list or pdp url: ", e);
-				this.isRunning = false;
-			} catch (MalformedURLException e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing URL to create topic for Notification ", e);
-			}
-			if(aURL != null){
-				String consumerTopic = aURL.getHost() + aURL.getPort() + "UpdateRequest";
-				SendMessage(consumerTopic, "Starting-Topic");
-				final LinkedList<String> urlList = new LinkedList<> ();
-				for ( String u : clusterList.split ( "," ) ){
-					urlList.add ( u );
-				}
+    private String topic = null;
+    private CambriaConsumer cConsumer = null;
+    private static String clusterList = null;
+    private static String update = null;
+    private BusConsumer dmaapConsumer = null;
+    private List<String> dmaapList = null;
+    private static String propNotificationType = null;
+    private static String aafLogin = null;
+    private static String aafPassword = null;
 
-				try {
-					CConsumer = CambriaClientFactory.createConsumer ( null, urlList, consumerTopic , group, id, 20*1000, 1000 );
-				} catch (MalformedURLException | GeneralSecurityException e1) {
-					LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create UEB Consumer: ", e1);
-				}
+    public volatile boolean isRunning = false;
 
-				while (this.isRunning()) {
-					LOGGER.debug("While loop test _ take out ");
-					try {
-						for ( String msg : CConsumer.fetch () ){		
-							LOGGER.debug("Manual Notification Recieved Message " + msg + " from UEB cluster : ");
-							returnTopic = processMessage(msg);
-							if(returnTopic != null){
-								SendMessage(returnTopic, update);
-							}
-						}
-					} catch (IOException e) {
-						LOGGER.debug(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing UEB message" + e);
-					}
-				}
-				LOGGER.debug("Stopping UEB Consumer loop will no longer fetch messages from the cluster");	
-			}
-		} else if ("dmaap".equals(propNotificationType)) {
-			String dmaapServers = null;
-			try {
-				dmaapServers = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS);
-				topic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC);
-				aafLogin = XACMLProperties.getProperty("DMAAP_AAF_LOGIN");
-				aafPassword = XACMLProperties.getProperty("DMAAP_AAF_PASSWORD");
-			} catch (Exception e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get DMaaP servers list:", e);
-				this.isRunning = false;
-			} 
-			
-			if(dmaapServers==null || topic==null){
-				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
-				try {
-					throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
-				} catch (Exception e) {
-					LOGGER.error(e);
-				}
-			}
-			
-			dmaapServers.trim();
-			topic.trim();
-			aafLogin.trim();
-			aafPassword.trim();
-			
-			String consumerTopic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC).trim();
-			SendMessage(consumerTopic, "Starting-Topic");
-			dmaapList = new ArrayList<>();
-			for ( String u : dmaapServers.split ( "," ) ){
-				dmaapList.add ( u );
-			}
-			
-			try {
-				
-				dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, consumerTopic, aafLogin, aafPassword, group, id, 20*1000, 1000);
-			} catch (Exception e1) {
-				LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e1);
-			}
+    public synchronized boolean isRunning() {
+        return this.isRunning;
+    }
 
-			while (this.isRunning()) {
-				LOGGER.debug("While loop test _ take out ");
-				try {
-					for ( String msg : dmaapConsumer.fetch () ){		
-						LOGGER.debug("Manual Notification Recieved Message " + msg + " from DMaaP server : ");
-						returnTopic = processMessage(msg);
-						if(returnTopic != null){
-							SendMessage(returnTopic, update);
-						}
-					}
-				}catch (Exception e) {
-					LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing DMaaP message: ", e);				}
-			}
-			LOGGER.debug("Stopping DMaaP Consumer loop will no longer fetch messages from the servers");	
-		}
-	}
+    public synchronized void terminate() {
+        this.isRunning = false;
+    }
 
-	private void SendMessage( String topic, String message) {
-		CambriaPublisher pub = null;
-		BusPublisher publisher = null;
-		try {
-			if ("ueb".equals(propNotificationType)) {
-				pub = CambriaClientFactory.createSimplePublisher (null, clusterList, topic );
-				pub.send( "pdpReturnMessage", message );
-				LOGGER.debug("Sending Message to UEB topic: " + topic);
-				pub.close();
-				
-			} else if ("dmaap".equals(propNotificationType)){
-				publisher = new BusPublisher.DmaapPublisherWrapper(dmaapList,topic,aafLogin,aafPassword);
-				publisher.send( "pdpReturnMessage", message );
-				LOGGER.debug("Sending to Message to DMaaP topic: " + topic);
-				publisher.close();
-			}
+    /**
+     * 
+     * This is our thread that runs on startup if the system is configured to UEB to accept manual update requests
+     * 
+     */
+    @Override
+    public void run() {
+        synchronized (this) {
+            this.isRunning = true;
+        }
 
-		} catch (Exception e) {
-			LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Error sending notification update: ", e);
-		}
-		if(pub != null){
-			try {
-				pub.send( "pdpReturnMessage", message );
-				LOGGER.debug("Sending to Message to tpoic" + topic);
-				pub.close();
-			} catch (IOException e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Error sending notification update" +e);
-			}	
-		}		
-	}
+        URL aURL = null;
+        String group = UUID.randomUUID().toString();
+        String id = "0";
+        String returnTopic = null;
+        setPropNotification();
+        if ("ueb".equals(propNotificationType)) {
+            try {
+                setCluster();
+                String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID);
+                aURL = new URL(url);
+                topic = aURL.getHost() + aURL.getPort();
+            } catch (NumberFormatException e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get UEB cluster list or pdp url: ", e);
+                this.isRunning = false;
+            } catch (MalformedURLException e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+                        + "Error in processing URL to create topic for Notification ", e);
+            }
+            if (aURL != null) {
+                String consumerTopic = aURL.getHost() + aURL.getPort() + "UpdateRequest";
+                sendMessage(consumerTopic, "Starting-Topic");
+                final LinkedList<String> urlList = new LinkedList<>();
+                for (String u : clusterList.split(",")) {
+                    urlList.add(u);
+                }
 
-	private String processMessage(String msg) {
-		LOGGER.debug("notification message:  " + msg);
-		String[] UID = msg.split("=")[1].split("\"");
-		
-		String returnTopic = topic + UID[0];
-		if(msg.contains("Starting-Topic")){
-			return null;
-		}
-		return returnTopic;
-	}
-	public static void setUpdate(String update) {
-		ManualNotificationUpdateThread.update = update;
-	}
-	
+                try {
+                    cConsumer = CambriaClientFactory.createConsumer(null, urlList, consumerTopic, group, id, 20 * 1000,
+                            1000);
+                } catch (MalformedURLException | GeneralSecurityException e1) {
+                    LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create UEB Consumer: ", e1);
+                }
+
+                while (this.isRunning()) {
+                    LOGGER.debug("While loop test _ take out ");
+                    try {
+                        for (String msg : cConsumer.fetch()) {
+                            LOGGER.debug("Manual Notification Recieved Message " + msg + " from UEB cluster : ");
+                            returnTopic = processMessage(msg);
+                            if (returnTopic != null) {
+                                sendMessage(returnTopic, update);
+                            }
+                        }
+                    } catch (IOException e) {
+                        LOGGER.debug(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing UEB message" + e);
+                    }
+                }
+                LOGGER.debug("Stopping UEB Consumer loop will no longer fetch messages from the cluster");
+            }
+        } else if ("dmaap".equals(propNotificationType)) {
+            String dmaapServers = null;
+            try {
+                dmaapServers = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS);
+                topic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC);
+                setAAFCreds();
+            } catch (Exception e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to get DMaaP servers list:", e);
+                this.isRunning = false;
+            }
+
+            if (dmaapServers == null || topic == null) {
+                LOGGER.error(
+                        XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
+            }
+
+            dmaapServers = dmaapServers.trim();
+            topic = topic.trim();
+
+            String consumerTopic = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TOPIC).trim();
+            sendMessage(consumerTopic, "Starting-Topic");
+            dmaapList = new ArrayList<>();
+            for (String u : dmaapServers.split(",")) {
+                dmaapList.add(u);
+            }
+
+            try {
+                dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, consumerTopic, aafLogin, aafPassword,
+                        group, id, 20 * 1000, 1000);
+            } catch (Exception e1) {
+                LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e1);
+            }
+
+            while (this.isRunning()) {
+                LOGGER.debug("While loop test _ take out ");
+                try {
+                    for (String msg : dmaapConsumer.fetch()) {
+                        LOGGER.debug("Manual Notification Recieved Message " + msg + " from DMaaP server : ");
+                        returnTopic = processMessage(msg);
+                        if (returnTopic != null) {
+                            sendMessage(returnTopic, update);
+                        }
+                    }
+                } catch (Exception e) {
+                    LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in processing DMaaP message: ", e);
+                }
+            }
+            LOGGER.debug("Stopping DMaaP Consumer loop will no longer fetch messages from the servers");
+        }
+    }
+
+    private static void setAAFCreds() {
+        aafLogin = XACMLProperties.getProperty("DMAAP_AAF_LOGIN");
+        aafPassword = XACMLProperties.getProperty("DMAAP_AAF_PASSWORD");
+        if (aafLogin != null) {
+            aafLogin = aafLogin.trim();
+        }
+        if (aafPassword != null) {
+            aafPassword = aafPassword.trim();
+        }
+    }
+
+    private static void setCluster() {
+        clusterList = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS);
+        if (clusterList != null) {
+            clusterList = clusterList.trim();
+        }
+    }
+
+    private static void setPropNotification() {
+        propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE);
+    }
+
+    private void sendMessage(String topic, String message) {
+        CambriaPublisher pub = null;
+        BusPublisher publisher = null;
+        try {
+            if ("ueb".equals(propNotificationType)) {
+                pub = CambriaClientFactory.createSimplePublisher(null, clusterList, topic);
+                pub.send("pdpReturnMessage", message);
+                LOGGER.debug("Sending Message to UEB topic: " + topic);
+                pub.close();
+
+            } else if ("dmaap".equals(propNotificationType)) {
+                publisher = new BusPublisher.DmaapPublisherWrapper(dmaapList, topic, aafLogin, aafPassword);
+                publisher.send("pdpReturnMessage", message);
+                LOGGER.debug("Sending to Message to DMaaP topic: " + topic);
+                publisher.close();
+            }
+
+        } catch (Exception e) {
+            LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error sending notification update: ", e);
+        }
+        if (pub != null) {
+            try {
+                pub.send("pdpReturnMessage", message);
+                LOGGER.debug("Sending to Message to tpoic" + topic);
+                pub.close();
+            } catch (IOException e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error sending notification update" + e);
+            }
+        }
+    }
+
+    private String processMessage(String msg) {
+        LOGGER.debug("notification message:  " + msg);
+        String[] uID = msg.split("=")[1].split("\"");
+
+        String returnTopic = topic + uID[0];
+        if (msg.contains("Starting-Topic")) {
+            return null;
+        }
+        return returnTopic;
+    }
+
+    public static void setUpdate(String update) {
+        ManualNotificationUpdateThread.update = update;
+    }
+
 }
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java
index 109d421..577d5b3 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationController.java
@@ -59,284 +59,301 @@
 import com.fasterxml.jackson.databind.ObjectWriter;
 
 /**
- * NotificationController Checks for the Updated and Removed policies. It
- * notifies the Server to send Notifications to the Client.
+ * NotificationController Checks for the Updated and Removed policies. It notifies the Server to send Notifications to
+ * the Client.
  * 
  * @version 0.2
  *
  */
 public class NotificationController {
-	private static final Logger LOGGER = FlexLogger.getLogger(NotificationController.class);
-	private static Notification record = new Notification();
-	private PDPStatus oldStatus = null;
-	private Removed removed = null;
-	private Updated updated = null;
-	private ManualNotificationUpdateThread registerMaunualNotificationRunnable = null;
-	private Thread manualNotificationThread = null;
-	private boolean manualThreadStarted = false;
-	
-	private static String notificationJSON = null;
-	private static String propNotificationType = null;
-	private static String pdpURL = null;
-	private static Boolean notificationFlag = false; 
-	
-	public void check(PDPStatus newStatus,Map<String, PolicyDef> policyContainer) {
-		boolean updated = false;
-		boolean removed = false;
-		Notification notification = new Notification();
-		HashSet<Removed> removedPolicies = new HashSet<>();
-		HashSet<Updated> updatedPolicies = new HashSet<>();
+    private static final Logger LOGGER = FlexLogger.getLogger(NotificationController.class);
+    private static Notification record = new Notification();
+    private PDPStatus oldStatus = null;
+    private Removed removed = null;
+    private Updated updated = null;
+    private ManualNotificationUpdateThread registerMaunualNotificationRunnable = null;
+    private Thread manualNotificationThread = null;
+    private boolean manualThreadStarted = false;
 
-		if (oldStatus == null) {
-			oldStatus = newStatus;
-		}
-		// Debugging purpose only.
-		LOGGER.debug("old config Status :" + oldStatus.getStatus());
-		LOGGER.debug("new config Status :" + newStatus.getStatus());
+    private static String notificationJSON = null;
+    private static String propNotificationType = null;
+    private static String pdpURL = null;
+    private static Boolean notificationFlag = false;
 
-		// Depending on the above condition taking the Change as an Update.
-		if (oldStatus.getStatus().toString() != newStatus.getStatus().toString()) {
-			LOGGER.info("There is an Update to the PDP");
-			LOGGER.debug(oldStatus.getLoadedPolicies());
-			LOGGER.debug(newStatus.getLoadedPolicies());
-			// Check if there is an Update/additions in the policy.
-			for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) {
-				boolean change = true;
-				for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) {
-					// Check if there are same policies.
-					if (oldPolicy.getId().equals(newPolicy.getId())) {
-						// Check if they have same version.
-						if (oldPolicy.getVersion().equals(newPolicy.getVersion())) {
-							change = false;
-						}
-					}
-				}
-				// if there is a change Send the notifications to the Client.
-				if (change) {
-					sendUpdate(newPolicy, policyContainer);
-					updated = true;
-					updatedPolicies.add(this.updated);
-				}
-			}
-			// Check if there is any removal of policy.
-			for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) {
-				boolean change = true;
-				for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) {
-					// Check if there are same policies.
-					if (oldPolicy.getId().equals(newPolicy.getId())) {
-						// Check if they have same version.
-						if (oldPolicy.getVersion().equals(newPolicy.getVersion())) {
-							change = false;
-						}
-					}
-				}
-				// if there is a change Send the notifications to the Client.
-				if (change) {
-					sendremove(oldPolicy);
-					removed = true;
-					removedPolicies.add(this.removed);
-				}
-			}
-		}
-		// At the end the oldStatus must be updated with the newStatus.
-		oldStatus = newStatus;
-		// Sending Notification to the Server to pass over to the clients
-		if (updated || removed) {
-			// Call the Notification Server..
-			notification.setRemovedPolicies(removedPolicies);
-			notification.setLoadedPolicies(updatedPolicies);
-			notification = setUpdateTypes(updated, removed, notification);
-			ObjectWriter om = new ObjectMapper().writer();
-			try {
-				notificationJSON = om.writeValueAsString(notification);
-				LOGGER.info(notificationJSON);
-				// NotificationServer Method here.
-				propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE);
-				pdpURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID);
-				if (("ueb".equals(propNotificationType)||"dmaap".equals(propNotificationType)) && !manualThreadStarted) {
-					LOGGER.debug("Starting  Thread to accept UEB or DMAAP notfications.");
-					this.registerMaunualNotificationRunnable = new ManualNotificationUpdateThread();
-					this.manualNotificationThread = new Thread(this.registerMaunualNotificationRunnable);
-					this.manualNotificationThread.start();
-					manualThreadStarted = true;
-				}
-				String notificationJSON= null;
-				notificationFlag = true;
-				try{
-					notificationJSON= record(notification);
-				}catch(Exception e){
-					LOGGER.error(e);
-				}
-				NotificationServer.setUpdate(notificationJSON);
-				ManualNotificationUpdateThread.setUpdate(notificationJSON);
-			} catch (JsonProcessingException e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() +e);
-			}
-		}
-	}
-	
-	public static void sendNotification(){
-		if(notificationFlag){
-			try {
-				NotificationServer.sendNotification(notificationJSON, propNotificationType, pdpURL);
-			} catch (Exception e) {
-				LOGGER.info(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in sending the Event Notification: "+ e.getMessage() + e);
-			}
-			notificationFlag = false;
-		}
-	}
-	
-	private void sendremove(PDPPolicy oldPolicy) {
-		removed = new Removed();
-		// Want to know what is removed ?
-		LOGGER.info("Policy removed: " + oldPolicy.getId()+ " with version number: " + oldPolicy.getVersion());
-		removed.setPolicyName(oldPolicy.getId());
-		removed.setVersionNo(oldPolicy.getVersion());
-		removeFile(oldPolicy);
-	}
+    public void check(PDPStatus newStatus, Map<String, PolicyDef> policyContainer) {
+        boolean updated = false;
+        boolean removed = false;
+        Notification notification = new Notification();
+        HashSet<Removed> removedPolicies = new HashSet<>();
+        HashSet<Updated> updatedPolicies = new HashSet<>();
 
-	private void sendUpdate(PDPPolicy newPolicy,Map<String, PolicyDef> policyContainer) {
-		updated = new Updated();
-		// Want to know what is new ?
-		LOGGER.info("The new Policy is: " + newPolicy.getId());
-		LOGGER.info("The version no. is: " + newPolicy.getVersion());
-		updated.setPolicyName(newPolicy.getId());
-		updated.setVersionNo(newPolicy.getVersion());
-		updated.setUpdateType(UpdateType.NEW);
-		// If the policy is of Config type then retrieve its matches.
-		if (newPolicy.getName().contains(".Config_")) {
-			// Take a Configuration copy to PDP webapps. 
-			final String urlStart = "attributeId=URLID,expression";
-			final String urlEnd = "}}},{";
-			String policy = policyContainer.get(newPolicy.getId()).toString(); 
-			if(policy.contains(urlStart)){
-				String urlFinePartOne = policy.substring(policy.indexOf(urlStart)+urlStart.length());
-				String urlFinePart = urlFinePartOne.substring(0,urlFinePartOne.indexOf(urlEnd));
-				String urlString = urlFinePart.substring(urlFinePart.indexOf("value=$URL")+6); 
-				callPap(urlString, "Config");
-			}
-			Iterator<AnyOf> anyOfs = policyContainer.get(newPolicy.getId()).getTarget().getAnyOfs();
-			while (anyOfs.hasNext()) {
-				AnyOf anyOf = anyOfs.next();
-				Iterator<AllOf> allOfs = anyOf.getAllOfs();
-				while (allOfs.hasNext()) {
-					AllOf allOf = allOfs.next();
-					Iterator<Match> matches = allOf.getMatches();
-					HashMap<String, String> matchValues = new HashMap<>();
-					while (matches.hasNext()) {
-						Match match = matches.next();
-						LOGGER.info("Attribute Value is: "+ match.getAttributeValue().getValue().toString());
-						String[] result = match.getAttributeRetrievalBase().toString().split("attributeId=");
-						result[1] = result[1].replaceAll("}", "");
-						if (!result[1].equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")) {
-							LOGGER.info("Attribute id is: " + result[1]);
-						}
-						matchValues.put(result[1], match.getAttributeValue().getValue().toString());
-						LOGGER.info("Match is : "+ result[1]+ " , "	+ match.getAttributeValue().getValue().toString());
-					}
-					updated.setMatches(matchValues);
-				}
-			}
-		}else if(newPolicy.getName().contains(".Action_")){
-			// Take Configuration copy to PDP Webapps.
-			// Action policies have .json as extension. 
-			String urlString = "$URL/Action/" + newPolicy.getId().substring(0, newPolicy.getId().lastIndexOf(".")) + ".json";
-			callPap(urlString, "Action");
-		}
-	}
+        if (oldStatus == null) {
+            oldStatus = newStatus;
+        }
+        // Debugging purpose only.
+        LOGGER.debug("old config Status :" + oldStatus.getStatus());
+        LOGGER.debug("new config Status :" + newStatus.getStatus());
 
-	// Adding this for Recording the changes to serve Polling requests..
-	private static String record(Notification notification) throws Exception {
-		// Initialization with updates.
-		if (record.getRemovedPolicies() == null	|| record.getLoadedPolicies() == null) {
-			record.setRemovedPolicies(notification.getRemovedPolicies());
-			record.setLoadedPolicies(notification.getLoadedPolicies());
-		} else {
-			// Check if there is anything new and update the record..
-			if (record.getLoadedPolicies() != null	|| record.getRemovedPolicies() != null) {
-				HashSet<Removed> removedPolicies = (HashSet<Removed>) record.getRemovedPolicies();
-				HashSet<Updated> updatedPolicies = (HashSet<Updated>) record.getLoadedPolicies();
+        // Depending on the above condition taking the Change as an Update.
+        if (oldStatus.getStatus().toString() != newStatus.getStatus().toString()) {
+            LOGGER.info("There is an Update to the PDP");
+            LOGGER.debug(oldStatus.getLoadedPolicies());
+            LOGGER.debug(newStatus.getLoadedPolicies());
+            // Check if there is an Update/additions in the policy.
+            for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) {
+                boolean change = true;
+                for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) {
+                    // Check if there are same policies.
+                    if (oldPolicy.getId().equals(newPolicy.getId())) {
+                        // Check if they have same version.
+                        if (oldPolicy.getVersion().equals(newPolicy.getVersion())) {
+                            change = false;
+                        }
+                    }
+                }
+                // if there is a change Send the notifications to the Client.
+                if (change) {
+                    sendUpdate(newPolicy, policyContainer);
+                    updated = true;
+                    updatedPolicies.add(this.updated);
+                }
+            }
+            // Check if there is any removal of policy.
+            for (PDPPolicy oldPolicy : oldStatus.getLoadedPolicies()) {
+                boolean change = true;
+                for (PDPPolicy newPolicy : newStatus.getLoadedPolicies()) {
+                    // Check if there are same policies.
+                    if (oldPolicy.getId().equals(newPolicy.getId())) {
+                        // Check if they have same version.
+                        if (oldPolicy.getVersion().equals(newPolicy.getVersion())) {
+                            change = false;
+                        }
+                    }
+                }
+                // if there is a change Send the notifications to the Client.
+                if (change) {
+                    sendremove(oldPolicy);
+                    removed = true;
+                    removedPolicies.add(this.removed);
+                }
+            }
+        }
+        // At the end the oldStatus must be updated with the newStatus.
+        oldStatus = newStatus;
+        // Sending Notification to the Server to pass over to the clients
+        if (updated || removed) {
+            // Call the Notification Server..
+            notification.setRemovedPolicies(removedPolicies);
+            notification.setLoadedPolicies(updatedPolicies);
+            notification = setUpdateTypes(updated, removed, notification);
+            ObjectWriter om = new ObjectMapper().writer();
+            try {
+                setNotificationJSON(om.writeValueAsString(notification));
+                LOGGER.info(notificationJSON);
+                // NotificationServer Method here.
+                setPropNotification();
+                if (("ueb".equals(propNotificationType) || "dmaap".equals(propNotificationType))
+                        && !manualThreadStarted) {
+                    LOGGER.debug("Starting  Thread to accept UEB or DMAAP notfications.");
+                    this.registerMaunualNotificationRunnable = new ManualNotificationUpdateThread();
+                    this.manualNotificationThread = new Thread(this.registerMaunualNotificationRunnable);
+                    this.manualNotificationThread.start();
+                    manualThreadStarted = true;
+                }
+                String notificationJSONString = null;
+                setNotificationFlag(true);
+                try {
+                    notificationJSONString = record(notification);
+                } catch (Exception e) {
+                    LOGGER.error(e);
+                }
+                NotificationServer.setUpdate(notificationJSONString);
+                ManualNotificationUpdateThread.setUpdate(notificationJSONString);
+            } catch (JsonProcessingException e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
+            }
+        }
+    }
 
-				// Checking with New updated policies.
-				if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
-					for (Updated newUpdatedPolicy : notification.getLoadedPolicies()) {
-						// If it was removed earlier then we need to remove from our record
-						Iterator<Removed> oldRemovedPolicy = removedPolicies.iterator();
-						while (oldRemovedPolicy.hasNext()) {
-							Removed policy = oldRemovedPolicy.next();
-							if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) {
-								if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) {
-									oldRemovedPolicy.remove();
-								}
-							}
-						}
-						// If it was previously updated need to Overwrite it to the record.
-						Iterator<Updated> oldUpdatedPolicy = updatedPolicies.iterator();
-						while (oldUpdatedPolicy.hasNext()) {
-							Updated policy = oldUpdatedPolicy.next();
-							if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) {
-								if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) {
-									oldUpdatedPolicy.remove();
-								}
-							}
-						}
-						updatedPolicies.add(newUpdatedPolicy);
-					}
-				}
-				// Checking with New Removed policies.
-				if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
-					for (Removed newRemovedPolicy : notification.getRemovedPolicies()) {
-						// If it was previously removed Overwrite it to the record.
-						Iterator<Removed> oldRemovedPolicy = removedPolicies.iterator();
-						while (oldRemovedPolicy.hasNext()) {
-							Removed policy = oldRemovedPolicy.next();
-							if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) {
-								if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) {
-									oldRemovedPolicy.remove();
-								}
-							}
-						}
-						// If it was added earlier then we need to remove from our record.
-						Iterator<Updated> oldUpdatedPolicy = updatedPolicies.iterator();
-						while (oldUpdatedPolicy.hasNext()) {
-							Updated policy = oldUpdatedPolicy.next();
-							if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) {
-								if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) {
-									oldUpdatedPolicy.remove();
-								}
-							}
-						}
-						removedPolicies.add(newRemovedPolicy);
-					}
-				}
-				record.setRemovedPolicies(removedPolicies);
-				record.setLoadedPolicies(updatedPolicies);
-			}
-		}
-		// Send the Result to the caller.
-		ObjectWriter om = new ObjectMapper().writer();
-		String json = null;
-		try {
-			json = om.writeValueAsString(record);
-		} catch (JsonProcessingException e) {
-			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
-		}
-		LOGGER.info(json);
-		return json;
-	}
-	
-	private static Notification setUpdateTypes(boolean updated, boolean removed, Notification notification) {
-        if(notification!=null){
-            if(updated && removed){
+    private void setNotificationFlag(boolean value) {
+        notificationFlag = value;
+    }
+
+    private static void setNotificationJSON(String message) {
+        notificationJSON = message;
+    }
+
+    private static void setPropNotification() {
+        propNotificationType = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_TYPE);
+        pdpURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_ID);
+    }
+
+    public static void sendNotification() {
+        if (notificationFlag) {
+            try {
+                NotificationServer.sendNotification(notificationJSON, propNotificationType, pdpURL);
+            } catch (Exception e) {
+                LOGGER.info(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in sending the Event Notification: "
+                        + e.getMessage() + e);
+            }
+            notificationFlag = false;
+        }
+    }
+
+    private void sendremove(PDPPolicy oldPolicy) {
+        removed = new Removed();
+        // Want to know what is removed ?
+        LOGGER.info("Policy removed: " + oldPolicy.getId() + " with version number: " + oldPolicy.getVersion());
+        removed.setPolicyName(oldPolicy.getId());
+        removed.setVersionNo(oldPolicy.getVersion());
+        removeFile(oldPolicy);
+    }
+
+    private void sendUpdate(PDPPolicy newPolicy, Map<String, PolicyDef> policyContainer) {
+        updated = new Updated();
+        // Want to know what is new ?
+        LOGGER.info("The new Policy is: " + newPolicy.getId());
+        LOGGER.info("The version no. is: " + newPolicy.getVersion());
+        updated.setPolicyName(newPolicy.getId());
+        updated.setVersionNo(newPolicy.getVersion());
+        updated.setUpdateType(UpdateType.NEW);
+        // If the policy is of Config type then retrieve its matches.
+        if (newPolicy.getName().contains(".Config_")) {
+            // Take a Configuration copy to PDP webapps.
+            final String urlStart = "attributeId=URLID,expression";
+            final String urlEnd = "}}},{";
+            String policy = policyContainer.get(newPolicy.getId()).toString();
+            if (policy.contains(urlStart)) {
+                String urlFinePartOne = policy.substring(policy.indexOf(urlStart) + urlStart.length());
+                String urlFinePart = urlFinePartOne.substring(0, urlFinePartOne.indexOf(urlEnd));
+                String urlString = urlFinePart.substring(urlFinePart.indexOf("value=$URL") + 6);
+                callPap(urlString, "Config");
+            }
+            Iterator<AnyOf> anyOfs = policyContainer.get(newPolicy.getId()).getTarget().getAnyOfs();
+            while (anyOfs.hasNext()) {
+                AnyOf anyOf = anyOfs.next();
+                Iterator<AllOf> allOfs = anyOf.getAllOfs();
+                while (allOfs.hasNext()) {
+                    AllOf allOf = allOfs.next();
+                    Iterator<Match> matches = allOf.getMatches();
+                    HashMap<String, String> matchValues = new HashMap<>();
+                    while (matches.hasNext()) {
+                        Match match = matches.next();
+                        LOGGER.info("Attribute Value is: " + match.getAttributeValue().getValue().toString());
+                        String[] result = match.getAttributeRetrievalBase().toString().split("attributeId=");
+                        result[1] = result[1].replaceAll("}", "");
+                        if (!result[1].equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id")) {
+                            LOGGER.info("Attribute id is: " + result[1]);
+                        }
+                        matchValues.put(result[1], match.getAttributeValue().getValue().toString());
+                        LOGGER.info(
+                                "Match is : " + result[1] + " , " + match.getAttributeValue().getValue().toString());
+                    }
+                    updated.setMatches(matchValues);
+                }
+            }
+        } else if (newPolicy.getName().contains(".Action_")) {
+            // Take Configuration copy to PDP Webapps.
+            // Action policies have .json as extension.
+            String urlString = "$URL/Action/" + newPolicy.getId().substring(0, newPolicy.getId().lastIndexOf("."))
+                    + ".json";
+            callPap(urlString, "Action");
+        }
+    }
+
+    // Adding this for Recording the changes to serve Polling requests..
+    private static String record(Notification notification) {
+        // Initialization with updates.
+        if (record.getRemovedPolicies() == null || record.getLoadedPolicies() == null) {
+            record.setRemovedPolicies(notification.getRemovedPolicies());
+            record.setLoadedPolicies(notification.getLoadedPolicies());
+        } else {
+            // Check if there is anything new and update the record..
+            if (record.getLoadedPolicies() != null || record.getRemovedPolicies() != null) {
+                HashSet<Removed> removedPolicies = (HashSet<Removed>) record.getRemovedPolicies();
+                HashSet<Updated> updatedPolicies = (HashSet<Updated>) record.getLoadedPolicies();
+
+                // Checking with New updated policies.
+                if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
+                    for (Updated newUpdatedPolicy : notification.getLoadedPolicies()) {
+                        // If it was removed earlier then we need to remove from our record
+                        Iterator<Removed> oldRemovedPolicy = removedPolicies.iterator();
+                        while (oldRemovedPolicy.hasNext()) {
+                            Removed policy = oldRemovedPolicy.next();
+                            if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) {
+                                if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) {
+                                    oldRemovedPolicy.remove();
+                                }
+                            }
+                        }
+                        // If it was previously updated need to Overwrite it to the record.
+                        Iterator<Updated> oldUpdatedPolicy = updatedPolicies.iterator();
+                        while (oldUpdatedPolicy.hasNext()) {
+                            Updated policy = oldUpdatedPolicy.next();
+                            if (newUpdatedPolicy.getPolicyName().equals(policy.getPolicyName())) {
+                                if (newUpdatedPolicy.getVersionNo().equals(policy.getVersionNo())) {
+                                    oldUpdatedPolicy.remove();
+                                }
+                            }
+                        }
+                        updatedPolicies.add(newUpdatedPolicy);
+                    }
+                }
+                // Checking with New Removed policies.
+                if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
+                    for (Removed newRemovedPolicy : notification.getRemovedPolicies()) {
+                        // If it was previously removed Overwrite it to the record.
+                        Iterator<Removed> oldRemovedPolicy = removedPolicies.iterator();
+                        while (oldRemovedPolicy.hasNext()) {
+                            Removed policy = oldRemovedPolicy.next();
+                            if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) {
+                                if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) {
+                                    oldRemovedPolicy.remove();
+                                }
+                            }
+                        }
+                        // If it was added earlier then we need to remove from our record.
+                        Iterator<Updated> oldUpdatedPolicy = updatedPolicies.iterator();
+                        while (oldUpdatedPolicy.hasNext()) {
+                            Updated policy = oldUpdatedPolicy.next();
+                            if (newRemovedPolicy.getPolicyName().equals(policy.getPolicyName())) {
+                                if (newRemovedPolicy.getVersionNo().equals(policy.getVersionNo())) {
+                                    oldUpdatedPolicy.remove();
+                                }
+                            }
+                        }
+                        removedPolicies.add(newRemovedPolicy);
+                    }
+                }
+                record.setRemovedPolicies(removedPolicies);
+                record.setLoadedPolicies(updatedPolicies);
+            }
+        }
+        // Send the Result to the caller.
+        ObjectWriter om = new ObjectMapper().writer();
+        String json = null;
+        try {
+            json = om.writeValueAsString(record);
+        } catch (JsonProcessingException e) {
+            LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
+        }
+        LOGGER.info(json);
+        return json;
+    }
+
+    private static Notification setUpdateTypes(boolean updated, boolean removed, Notification notification) {
+        if (notification != null) {
+            if (updated && removed) {
                 notification.setNotificationType(NotificationType.BOTH);
-                if(notification.getLoadedPolicies()!=null){
-                    HashSet<Updated> updatedPolicies = new HashSet<>(); 
-                    for(Updated oldUpdatedPolicy: notification.getLoadedPolicies()){
+                if (notification.getLoadedPolicies() != null) {
+                    HashSet<Updated> updatedPolicies = new HashSet<>();
+                    for (Updated oldUpdatedPolicy : notification.getLoadedPolicies()) {
                         Updated updatePolicy = oldUpdatedPolicy;
-                        if(notification.getRemovedPolicies()!=null){
-                            for(RemovedPolicy removedPolicy: notification.getRemovedPolicies()){
+                        if (notification.getRemovedPolicies() != null) {
+                            for (RemovedPolicy removedPolicy : notification.getRemovedPolicies()) {
                                 String regex = ".(\\d)*.xml";
-                                if(removedPolicy.getPolicyName().replaceAll(regex, "").equals(oldUpdatedPolicy.getPolicyName().replaceAll(regex, ""))){
+                                if (removedPolicy.getPolicyName().replaceAll(regex, "")
+                                        .equals(oldUpdatedPolicy.getPolicyName().replaceAll(regex, ""))) {
                                     updatePolicy.setUpdateType(UpdateType.UPDATE);
                                     break;
                                 }
@@ -346,70 +363,76 @@
                     }
                     notification.setLoadedPolicies(updatedPolicies);
                 }
-            }else if(updated){
+            } else if (updated) {
                 notification.setNotificationType(NotificationType.UPDATE);
-            }else if(removed){
+            } else if (removed) {
                 notification.setNotificationType(NotificationType.REMOVE);
             }
         }
         return notification;
     }
-	
-	private void removeFile(PDPPolicy oldPolicy) {
-		try{
-			Path removedPolicyFile = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG)+File.separator+oldPolicy.getId());
-			Files.deleteIfExists(removedPolicyFile);
-			boolean delete=false;
-			File dir= null;
-			if(oldPolicy.getName().contains(".Config_")){
-				delete = true;
-				dir = new File(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+"Config");
-			}else if(oldPolicy.getName().contains(".Action_")){
-				delete = true;
-				dir = new File(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+"Action");
-			}
-			if(delete){
-				FileFilter fileFilter = new WildcardFileFilter(oldPolicy.getId().substring(0, oldPolicy.getId().lastIndexOf("."))+".*");
-				File[] configFile = dir.listFiles(fileFilter);
-				if(configFile.length==1){
-					Files.deleteIfExists(configFile[0].toPath());
-				}
-			}
-		}catch(Exception e){
-			LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Couldn't remove the policy/config file " + oldPolicy.getName() + e);
-		}
-	}
-	
-	private void callPap(String urlString, String type) {
-		Path configLocation = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS)+File.separator+type);
-		if(Files.notExists(configLocation)){
-			try {
-				Files.createDirectories(configLocation);
-			} catch (IOException e) {
-				LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW +"Failed to create config directory: " + configLocation.toAbsolutePath().toString(), e);
-			}
-		}
-		PapUrlResolver papUrls = PapUrlResolver.getInstance();
-		while(papUrls.hasMoreUrls()){
-			String papPath = papUrls.getUrl();
-			papPath = papPath.substring(0, papPath.lastIndexOf("/pap"));
-			String papAddress= urlString.replace("$URL", papPath);
-			String fileName = papAddress.substring(papAddress.lastIndexOf("/")+1);
-			String fileLocation = configLocation.toString() + File.separator + fileName;
-			try {
-				URL papURL = new URL(papAddress);
-				LOGGER.info("Calling " +papAddress + " for Configuration Copy.");
-				URLConnection urlConnection = papURL.openConnection();
-				File file= new File(fileLocation);
-				try (InputStream is = urlConnection.getInputStream();
-						OutputStream os = new FileOutputStream(file)) {
-					IOUtils.copy(is, os);
-					break;
-				}
-			} catch (Exception e) {
-				LOGGER.error(e + e.getMessage());
-			}
-			papUrls.getNext();
-		}
-	}
+
+    private void removeFile(PDPPolicy oldPolicy) {
+        try {
+            Path removedPolicyFile = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_CONFIG)
+                    + File.separator + oldPolicy.getId());
+            Files.deleteIfExists(removedPolicyFile);
+            boolean delete = false;
+            File dir = null;
+            if (oldPolicy.getName().contains(".Config_")) {
+                delete = true;
+                dir = new File(
+                        XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + "Config");
+            } else if (oldPolicy.getName().contains(".Action_")) {
+                delete = true;
+                dir = new File(
+                        XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + "Action");
+            }
+            if (delete) {
+                FileFilter fileFilter = new WildcardFileFilter(
+                        oldPolicy.getId().substring(0, oldPolicy.getId().lastIndexOf(".")) + ".*");
+                File[] configFile = dir.listFiles(fileFilter);
+                if (configFile.length == 1) {
+                    Files.deleteIfExists(configFile[0].toPath());
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Couldn't remove the policy/config file "
+                    + oldPolicy.getName() + e);
+        }
+    }
+
+    private void callPap(String urlString, String type) {
+        Path configLocation = Paths
+                .get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_WEBAPPS) + File.separator + type);
+        if (Files.notExists(configLocation)) {
+            try {
+                Files.createDirectories(configLocation);
+            } catch (IOException e) {
+                LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
+                        + configLocation.toAbsolutePath().toString(), e);
+            }
+        }
+        PapUrlResolver papUrls = PapUrlResolver.getInstance();
+        while (papUrls.hasMoreUrls()) {
+            String papPath = papUrls.getUrl();
+            papPath = papPath.substring(0, papPath.lastIndexOf("/pap"));
+            String papAddress = urlString.replace("$URL", papPath);
+            String fileName = papAddress.substring(papAddress.lastIndexOf("/") + 1);
+            String fileLocation = configLocation.toString() + File.separator + fileName;
+            try {
+                URL papURL = new URL(papAddress);
+                LOGGER.info("Calling " + papAddress + " for Configuration Copy.");
+                URLConnection urlConnection = papURL.openConnection();
+                File file = new File(fileLocation);
+                try (InputStream is = urlConnection.getInputStream(); OutputStream os = new FileOutputStream(file)) {
+                    IOUtils.copy(is, os);
+                    break;
+                }
+            } catch (Exception e) {
+                LOGGER.error(e + e.getMessage());
+            }
+            papUrls.getNext();
+        }
+    }
 }
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java
index 690d8c5..2f3d582 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/notifications/NotificationServer.java
@@ -38,6 +38,7 @@
 import javax.websocket.Session;
 import javax.websocket.server.ServerEndpoint;
 
+import org.onap.policy.api.PolicyEngineException;
 import org.onap.policy.common.logging.eelf.MessageCodes;
 import org.onap.policy.common.logging.eelf.PolicyLogger;
 import org.onap.policy.common.logging.flexlogger.FlexLogger;
@@ -66,8 +67,6 @@
 	private static final Logger LOGGER	= FlexLogger.getLogger(NotificationServer.class);
 	private static Queue<Session> queue = new ConcurrentLinkedQueue<>();
 	private static String update = null;
-	private static  String hosts = null;
-	private static URL aURL = null;
 	
 	@OnOpen
 	public void openConnection(Session session) {
@@ -88,7 +87,7 @@
 	}
 	
 	@OnMessage
-	public void Message(String message, Session session) {
+	public void message(String message, Session session) {
 		
 		if(message.equalsIgnoreCase("Manual")) {
 			try {
@@ -101,14 +100,14 @@
 		}
 	}
 
-	public static void sendNotification(String notification, String propNotificationType, String pdpURL) throws Exception {
+	public static void sendNotification(String notification, String propNotificationType, String pdpURL) throws PolicyEngineException, IOException, InterruptedException {
 
 		LOGGER.debug("Notification set to " + propNotificationType);
 		if (propNotificationType.equals("ueb")){
 
 			String topic = null;
 			try {
-				aURL = new URL(pdpURL);
+				URL aURL = new URL(pdpURL);
 				topic = aURL.getHost() + aURL.getPort();
 			} catch (MalformedURLException e1) {
 				pdpURL = pdpURL.replace("/", "");
@@ -116,7 +115,7 @@
 				LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error in parsing out pdpURL for UEB notfication ");
 				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e1, "Error in parsing out pdpURL for UEB notfication ");
 			}
-			hosts = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS);
+			String hosts = XACMLProperties.getProperty(XACMLRestProperties.PROP_NOTIFICATION_SERVERS);
 			String apiKey = XACMLProperties.getProperty(XACMLRestProperties.PROP_UEB_API_KEY);
 			String apiSecret = XACMLProperties.getProperty(XACMLRestProperties.PROP_UEB_API_SECRET);
 
@@ -125,13 +124,13 @@
 			try {
 				if(hosts==null || topic==null || apiKey==null || apiSecret==null){
 					LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file ");
-					throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file ");
+					throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file ");
 				}
 
-				hosts.trim();
-				topic.trim();
-				apiKey.trim();
-				apiSecret.trim();
+				hosts = hosts.trim();
+				topic = topic.trim();
+				apiKey = apiKey.trim();
+				apiSecret = apiSecret.trim();
 				pub = new CambriaClientBuilders.PublisherBuilder ()
 						.usingHosts ( hosts )
 						.onTopic ( topic )
@@ -175,13 +174,13 @@
 			try {
 				if(dmaapServers==null || topic==null){
 					LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
-					throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
+					throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
 				}
 				
-				dmaapServers.trim();
-				topic.trim();
-				aafLogin.trim();
-				aafPassword.trim();
+				dmaapServers= dmaapServers.trim();
+				topic= topic.trim();
+				aafLogin= aafLogin.trim();
+				aafPassword= aafPassword.trim();
 				
 				List<String> dmaapList = null;
 				if(dmaapServers.contains(",")) {
diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java
index aa55a2a..fe4ce05 100644
--- a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java
+++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/test/PolicyEngineServicesTest.java
@@ -195,6 +195,9 @@
 	
 	@Test
 	public void getNotificationTopicValidPassTest() throws Exception{
+	    XACMLProperties.reloadProperties();
+        System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/notification.xacml.pdp.properties");
+        XACMLProperties.getProperties();
 		// Add a Topic. 
 		mockMvc.perform(post("/getNotification").headers(headers).header(UUIDHEADER, "123").content("test")).andExpect(status().isOk());
 		// Try to add same topic should fail.  
diff --git a/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties b/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties
new file mode 100644
index 0000000..9ca1bba
--- /dev/null
+++ b/ONAP-PDP-REST/src/test/resources/notification.xacml.pdp.properties
@@ -0,0 +1,171 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP-PDP-REST
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+# Default XACML Properties File for PDP RESTful servlet
+#
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+# NOT USED SEE BELOW xacml.pipFinderFactory=org.onap.policy.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=org.onap.policy.xacml.custom.OnapFunctionDefinitionFactory
+# NOT USED SEE BELOW xacml.att.policyFinderFactory=org.onap.policy.pdp.std.StdPolicyFinderFactory
+# creteUpdate Policy Implementation Class details. 
+createUpdatePolicy.impl.className=org.onap.policy.pdp.rest.api.services.CreateUpdatePolicyServiceImpl
+# AAF Implementation class details
+aafClient.impl.className=org.onap.policy.utils.AAFPolicyClientImpl
+#
+# AT&T RESTful PDP Implementation Factories
+#
+xacml.pipFinderFactory=org.onap.policy.pdp.rest.impl.XACMLPdpPIPFinderFactory
+xacml.att.policyFinderFactory=org.onap.policy.pdp.rest.XACMLPdpPolicyFinderFactory
+#
+# When set to true, this flag tells the StdPolicyFinderFactory to combined all the root policy files into
+# into one PolicySet and use the given Policy Algorithm.
+#
+xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-permit-overrides
+#
+# PDP RESTful API properties
+# 
+# Set this to the address where the XACML-PAP-REST servlet is running
+xacml.rest.pap.url=http://localhost:8070/pap/
+
+#if multiple paps exist, the xacml.rest.pap.url can be removed and they can be defined like this:
+#xacml.rest.pap.urls=http://localhost:9090/pap/,http://localhost:9091/pap/
+
+#
+# Give the running PDP an ID for the PAP. The url that its running as is a good choice.
+# The PAP identifies PDP's using the URL of the PDP.
+#
+xacml.rest.pdp.id=http://localhost:8082/pdp/
+
+# Give the port number used for the PDP
+
+xacml.jmx.port=0
+
+
+# Notification Properties
+# Notifcation type: websocket, ueb or dmaap... if left blank websocket is the default
+NOTIFICATION_TYPE=websocket
+NOTIFICATION_SERVERS=test
+NOTIFICATION_TOPIC=test
+NOTIFICATION_DELAY=5000
+UEB_API_KEY=
+UEB_API_SECRET=
+DMAAP_AAF_LOGIN=test
+DMAAP_AAF_PASSWORD=test
+
+#
+# Set the directory where the PDP holds its Policy Cache and PIP Configuration
+#
+xacml.rest.pdp.config=config
+
+xacml.rest.pdp.webapps=/home/users/PolicyEngine/webapps/ConfigPAP/
+#
+# Initialize register with PAP servlet
+#
+xacml.rest.pdp.register=true
+#
+# Sleep period in seconds between register attempts
+#
+xacml.rest.pdp.register.sleep=15
+#
+# number of attempts to register. -1 means keep trying forever.
+#
+xacml.rest.pdp.register.retries=-1
+#
+# max number of bytes in a POST of a XML/JSON request
+# old value #32767
+xacml.rest.pdp.maxcontent=99999999 
+#
+# Set UserID here
+xacml.rest.pdp.userid=testpdp
+# Set Password here
+xacml.rest.pdp.password=alpha456
+
+# id PAP
+xacml.rest.pap.userid=testpap
+#if multiple paps have different logins, they can be defined like this:
+#http\://localhost\:9090/pap/.xacml.rest.pap.userid=testpap
+
+# pass PAP
+xacml.rest.pap.password=alpha123
+#http\://localhost\:9090/pap/.xacml.rest.pap.password=alpha123
+
+# Delay for Notifications Don't change this. Value in milliSec.  
+xacml.rest.notification.delay=30
+# Buffer Size. 
+REQUEST_BUFFER_SIZE=15
+
+#properties for MySql xacml database:  PLEASE DO NOT REMOVE... NEEDED FOR APIs
+javax.persistence.jdbc.driver=com.mysql.jdbc.Driver
+javax.persistence.jdbc.url=jdbc:mysql://localhost:3306/xacml
+javax.persistence.jdbc.user=policy_user
+javax.persistence.jdbc.password=policy_user
+
+
+#***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java***
+
+#The name of the PDP.  Must be unique across the system
+xacml.rest.pdp.resource.name=site_1.pdp_1
+
+#***Properties for IntegrityMonitor integration defined in IntegrityMonitorProperties.java***
+
+#Interval between forward progress counter updates in seconds
+fp_monitor_interval=30
+
+#Number of forward progress counter failures before failover
+failed_counter_threshold=3
+
+#Interval in seconds between test transactions if there is no other traffic
+test_trans_interval=10
+
+#Interval in seconds between updates of the forward progress counter in the DB
+write_fpc_interval=5
+
+#Name of the site
+site_name=site_1
+
+#Node type
+node_type=pdp_xacml
+
+#Dependency groups are groups of resources upon which a node operational state is dependent upon). 
+#Each group is a comma-separated list of resource names and groups are separated by a semicolon.
+#A group may contain one or more members. Resource names must match the resource names defined
+#in the respective servers' properties files
+dependency_groups=site_1.pdplp_1;site_1.astragw_1;site_1.brmsgw_1
+
+# this can be DEVL, TEST, PROD 
+ENVIRONMENT=DEVL
+xacml.rest.pep.idfile = src/test/resources/client.properties
+
+#AAF Policy Name space
+#Not Mandatory for Open Onap
+policy.aaf.namespace = 
+policy.aaf.resource = 
+#
+DMAAP_AAF_LOGIN =