diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/AttributeType.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/AttributeType.java
index 2a88791..44cf441 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/AttributeType.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/AttributeType.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Attribute Types that is used as a part of
  * {@link org.openecomp.policy.api.PolicyParameters}.
@@ -63,4 +65,14 @@
 	public String toString() {
 		return this.name;
 	}
+	
+	@JsonCreator
+    public static AttributeType create (String value) {
+        for(AttributeType type: values()){
+            if(type.toString().equalsIgnoreCase(value)){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyCondition.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyCondition.java
index 3440c99..4ef348c 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyCondition.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyCondition.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Policy Delete Condition that is used as a part of
  * {@link org.openecomp.policy.api.DeletePolicyParameters}.
@@ -50,4 +52,14 @@
 	public String toString(){
 		return this.name;
 	}
+
+	@JsonCreator
+    public static DeletePolicyCondition create (String value) {
+        for(DeletePolicyCondition type: values()){
+            if(type.toString().equals(value) || type.equals(DeletePolicyCondition.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyParameters.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyParameters.java
index 3999c5e..3121297 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyParameters.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DeletePolicyParameters.java
@@ -31,6 +31,7 @@
 public class DeletePolicyParameters {
 	
 	private String policyName;
+	private String policyType;
 	private String policyComponent;
 	private DeletePolicyCondition deleteCondition;
 	private String pdpGroup;
@@ -56,6 +57,18 @@
 		return policyComponent;
 	}
 	/**
+	 * @return the policyType
+	 */
+	public String getPolicyType() {
+		return policyType;
+	}
+	/**
+	 * @param policyType the policyType to set
+	 */
+	public void setPolicyType(String policyType) {
+		this.policyType = policyType;
+	}
+	/**
 	 * @param policyComponent the policyComponent to set
 	 */
 	public void setPolicyComponent(String policyComponent) {
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryParameters.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryParameters.java
index 1506eff..cf70caf 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryParameters.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryParameters.java
@@ -20,14 +20,13 @@
 
 package org.openecomp.policy.api;
 
-import java.util.Map;
 import java.util.UUID;
 
 public class DictionaryParameters {
 	
 	private DictionaryType dictionaryType;
 	private String dictionary;
-	private Map<AttributeType, Map<String,String>> dictionaryFields;
+	private String dictionaryJson;
 	private UUID requestID;
 	
 	
@@ -58,14 +57,14 @@
 	/**
 	 * @return the dictionaryFields
 	 */
-	public Map<AttributeType, Map<String,String>> getDictionaryFields() {
-		return dictionaryFields;
+	public String getDictionaryJson() {
+		return dictionaryJson;
 	}
 	/**
 	 * @param dictionaryFields the dictionaryFields to set
 	 */
-	public void setDictionaryFields(Map<AttributeType, Map<String,String>> dictionaryFields) {
-		this.dictionaryFields = dictionaryFields;
+	public void setDictionaryJson(String dictionaryJson) {
+		this.dictionaryJson = dictionaryJson;
 	}
 	/**
 	 * @return the requestID
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryResponse.java
new file mode 100644
index 0000000..dd73798
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryResponse.java
@@ -0,0 +1,41 @@
+package org.openecomp.policy.api;
+
+import java.util.Map;
+
+import javax.json.JsonObject;
+
+public interface DictionaryResponse {
+	
+	/**
+	 * Gets the <code>String</code> of the DictionaryItemsMessage from <code>DictionaryResponse</code>.
+	 * 
+	 * @return the <code>String</code> which consists of DictionaryItemsMessage from <code>DictionaryResponse</code>
+	 */
+	public String getResponseMessage();
+	
+	/**
+	 * Response code of type <code>Integer</code> which corresponds to the HTTP Response code explaining the response from Policy Engine. 
+	 * 
+	 * @return the responseCode in <code>Integer</code> format corresponding to the HTTP response code from Policy Engine. 
+	 */
+	public int getResponseCode();
+
+	
+	/**
+	 * Gets the <code>JsonObject</code> of all the Dictionary data retrieved
+	 * 
+	 * @return the <code>JsonObject</code> which consists of Dictionary data which has been retrieved.  
+	 */
+	public JsonObject getDictionaryJson();
+	
+	
+	/**
+	 * Gets the Key and Value pairs for each Dictionary item retrieved which can be used in the getDictionaryItems call.
+	 * 
+	 * @return <code>Map</code> of <code>String, String</code> which consists of the Key and Value pairs for each Dictionary item retrieved. 
+	 */
+	public Map<String,String> getDictionaryData();
+	
+
+
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryType.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryType.java
index 0935f64..b50f398 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryType.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/DictionaryType.java
@@ -20,19 +20,25 @@
 
 package org.openecomp.policy.api;
 
-public enum DictionaryType {
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+public enum DictionaryType{
 	/**
 	 * Indicates Common Dictionaries. 
 	 */
 	Common("Common"),
 	/**
+	 * Indicates Action Policy Dictionaries
+	 */
+	Action("Action"),
+	/**
 	 * Indicates ClosedLoop Policy Dictionaries. 
 	 */
 	ClosedLoop("ClosedLoop"),
 	/**
 	 * Indicates Firewall Config Policy Dictionaries. 
 	 */
-	Firewall("FW"),
+	Firewall("Firewall"),
 	/**
 	 * Indicates Decision Policy Dictionaries. 
 	 */
@@ -44,7 +50,7 @@
 	/**
 	 * Indicates DCAE Micro Service Policy Dictionaries. 
 	 */
-	MicroService("MS"),
+	MicroService("MicroService"),
 	/**
 	 * Indicates Descriptive Scope Dictionaries
 	 */
@@ -53,6 +59,14 @@
 	 * Indicates Policy Scope Dictionaries
 	 */
 	PolicyScope("PolicyScope"),
+	/**
+	 * Indicates Enforcer Dictionaries
+	 */
+	Enforcer("Enforcer"),
+	/**
+	 * Indicates SafePolicy Dictionaries
+	 */
+	SafePolicy("SafePolicy"),
 	;
 	
 	private String name;
@@ -69,5 +83,14 @@
 		return this.name;
 	}
 	
+	@JsonCreator
+    public static DictionaryType create (String value) {
+        for(DictionaryType type: values()){
+            if(type.toString().equals(value) || type.equals(DictionaryType.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/ImportParameters.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/ImportParameters.java
index 299f29a..8823793 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/ImportParameters.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/ImportParameters.java
@@ -20,7 +20,6 @@
 
 package org.openecomp.policy.api;
 
-import java.util.List;
 import java.util.UUID;
 
 
@@ -35,12 +34,12 @@
 	private String description;
 	private UUID requestID;
 	private String filePath;
-	private String importBody;
 	private String version;
 	private IMPORT_TYPE importType;
 	
 	public enum IMPORT_TYPE {
-	    MICROSERVICE
+	    MICROSERVICE,
+	    BRMSPARAM
 	}
 
 	/**
@@ -118,24 +117,6 @@
 	public void setRequestID(UUID requestID) {
 		this.requestID = requestID;
 	}
-
-	/**
-	 * Gets the importBody of the new policy import. 
-	 * 
-	 * @return importBody the <code>String</code> format of the Policy Import Body
-	 */
-	public String getImportBody() {
-		return importBody;
-	}
-
-	/**
-	 * Sets the importBody of the Policy Import Body. 
-	 * 
-	 * @param importBody the <code>String</code> format of the Policy Import Body
-	 */
-	public void setImportBody(String importBody) {
-		this.importBody = importBody;
-	}
 	
 	/**
 	 * Gets the List of File Paths of the new import. 
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsRequestParameters.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsRequestParameters.java
new file mode 100644
index 0000000..4c10f39
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsRequestParameters.java
@@ -0,0 +1,21 @@
+package org.openecomp.policy.api;
+
+import java.util.UUID;
+
+public class MetricsRequestParameters {
+	private UUID requestID;
+	
+	/**
+	 * @return the requestID
+	 */
+	public UUID getRequestID() {
+		return requestID;
+	}
+	/**
+	 * @param requestID the requestID to set
+	 */
+	public void setRequestID(UUID requestID) {
+		this.requestID = requestID;
+	}
+
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsResponse.java
new file mode 100644
index 0000000..d96a6dc
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/MetricsResponse.java
@@ -0,0 +1,45 @@
+package org.openecomp.policy.api;
+
+public interface MetricsResponse {
+
+	/**
+	 * Gets the <code>String</code> of the metrics message from <code>MetricsResponse</code>.
+	 * 
+	 * @return the <code>String</code> which consists of the metrics message from <code>MetricsResponse</code>
+	 */
+	public String getResponseMessage();
+	
+	/**
+	 * Gets the response code of type <code>Integer</code> which corresponds to the HTTP Response code explaining the response from Policy Engine. 
+	 * 
+	 * @return the responseCode in <code>Integer</code> format corresponding to the HTTP response code from Policy Engine. 
+	 */
+	public int getResponseCode();
+
+	
+	/**
+	 * Gets the <code>Integer</code> value of the count of policies that reside on the PAP.
+	 * 
+	 * @return the <code>Integer</code> which consists of count of policies that reside on the PAP.  
+	 */
+	public int getPapMetrics();
+	
+	
+	/**
+	 * Gets the <code>Integer</code> value of the count of policies that reside on the PDP.
+	 * 
+	 * @return the <code>Integer</code> which consists of count of policies that reside on the PDP.  
+	 */
+	public int getPdpMetrics();
+	
+	
+	/**
+	 * Gets the <code>Integer</code> value of the total count of policies.
+	 * 
+	 * @return the <code>Integer</code> which consists of the total count of policies.  
+	 */
+	public int getMetricsTotal();
+	
+
+
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyClass.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyClass.java
index caf3c11..8b87f40 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyClass.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyClass.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Policy Types that is used as a part of
  * {@link org.openecomp.policy.api.PolicyParameters}.
@@ -53,4 +55,13 @@
 	public String toString() {
 		return this.name;
 	}
+	@JsonCreator
+    public static PolicyClass create (String value) {
+        for(PolicyClass type: values()){
+            if(type.toString().equals(value) || type.equals(PolicyClass.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigStatus.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigStatus.java
index 9f45b65..95d890d 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigStatus.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigStatus.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of PolicyConfigStatus that can be returned as a part of 
  * {@link org.openecomp.policy.api.PolicyConfig}.
@@ -65,4 +67,13 @@
 	public String toString(){
 		return this.name;
 	}
+	@JsonCreator
+    public static PolicyConfigStatus create (String value) {
+        for(PolicyConfigStatus type: values()){
+            if(type.toString().equals(value) || type.equals(PolicyConfigStatus.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigType.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigType.java
index 111c856..7b3ca2f 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigType.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyConfigType.java
@@ -20,13 +20,15 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Policy Config Types that is used as a part of
  * {@link org.openecomp.policy.api.PolicyParameters}.
  * 
  * @version 0.1
  */
-public enum PolicyConfigType {
+public enum PolicyConfigType{
 	/**
 	 * Indicates Base Config Policy. 
 	 */
@@ -59,8 +61,8 @@
 	
 	private String name;
 	
-	private PolicyConfigType(String typeName){
-		this.name = typeName;
+	private PolicyConfigType(String name){
+		this.name = name;
 	}
 	
 	/**
@@ -68,6 +70,16 @@
 	 * @return the <code>String</code> of the Type for this <code>PolicyClass</code>
 	 */
 	public String toString() {
-		return this.name;
+		return name;
 	}
+	
+	@JsonCreator
+    public static PolicyConfigType create (String value) {
+        for(PolicyConfigType type: values()){
+            if(type.toString().equals(value) || type.equals(PolicyConfigType.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyDecision.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyDecision.java
index 18d0669..a6b4bd2 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyDecision.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyDecision.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of PolicyDecision that can be returned as a part of 
  * {@link org.openecomp.policy.api.DecisionResponse} getDecision().
@@ -54,4 +56,13 @@
 	public String toString(){
 		return this.name;
 	}
+	@JsonCreator
+    public static PolicyDecision create (String value) {
+        for(PolicyDecision type: values()){
+            if(type.toString().equals(value) || type.equals(PolicyDecision.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyEngine.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyEngine.java
index 0b46c57..4fad508 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyEngine.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyEngine.java
@@ -33,7 +33,7 @@
 /**
  * PolicyEngine is the Interface that applications use to make policy queries against a PEPEngine 
  * 
- * @version 1.0
+ * @version 2.0
  */
 public class PolicyEngine{
 	private String propertyFilePath = null;
@@ -42,17 +42,67 @@
 	private NotificationHandler handler = null;
 	
 	/**
+	 * PolicyEngine Constructor with <code>String</code> format of propertiesFilePathname
+	 * 
+	 * @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname 
+	 * @throws PolicyEngineException PolicyEngine Exception
+	 */
+	public PolicyEngine(String propertiesFilePathname) throws PolicyEngineException {
+		this.propertyFilePath = propertiesFilePathname ; 
+		this.stdPolicyEngine= new StdPolicyEngine(this.propertyFilePath, (String)null);
+	}
+	
+	/**
+	 * PolicyEngine Constructor with <code>String</code> format of propertiesFilePathname
+	 * 
+	 * @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname
+	 * @param clientKey depicts String format of Password/ Client_Key.  
+	 * @throws PolicyEngineException PolicyEngine Exception
+	 */
+	public PolicyEngine(String propertiesFilePathname, String clientKey) throws PolicyEngineException {
+		this.propertyFilePath = propertiesFilePathname ; 
+		this.stdPolicyEngine= new StdPolicyEngine(this.propertyFilePath, clientKey);
+	}
+	
+	/**
+	 * PolicyEngine Constructor with <code>String</code> format of PropertiesFilePathname and <code>NotificationScheme</code>
+	 * 
+	 * @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname
+	 * @param scheme the <code>NotificationScheme</code> of {@link org.openecomp.policy.api.NotificationScheme} which defines the Notification Scheme
+	 * @throws PolicyEngineException PolicyEngine Exception
+	 */
+	public PolicyEngine(String propertiesFilePathname, NotificationScheme scheme) throws PolicyEngineException{
+		this.propertyFilePath = propertiesFilePathname;
+		this.scheme = scheme;
+		this.stdPolicyEngine = new StdPolicyEngine(this.propertyFilePath, this.scheme);
+	}
+	
+	/**
+	 * PolicyEngine Constructor with <code>String</code> format of PropertiesFilePathname, <code>NotificationScheme</code> and <code>NotificationHandler</code>
+	 *  
+	 *  @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname 
+	 *  @param scheme the <code>NotificationScheme</code> of {@link org.openecomp.policy.api.NotificationScheme} which defines the Notification Scheme
+	 *  @param handler the <code>NotificationHandler</code> of {@link org.openecomp.policy.api.NotificationHandler} which defines what should happen when a notification is received.
+	 *  @throws PolicyEngineException PolicyEngine Exception
+	 */
+	public PolicyEngine(String propertiesFilePathname, NotificationScheme scheme, NotificationHandler handler) throws PolicyEngineException {
+		this.propertyFilePath = propertiesFilePathname ;
+		this.scheme = scheme;
+		this.handler = handler;
+		this.stdPolicyEngine= new StdPolicyEngine(this.propertyFilePath,this.scheme,this.handler);
+	}
+	
+	/**
 	 * Gets the configuration from the PolicyDecisionPoint(PDP) for the <code>String</code> which represents the Policy File Name 
 	 * 
 	 * @param policyName the <code>String</code> format of the PolicyFile Name whose configuration is required. 
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration. 
-	 * @throws PolicyConfigException
-	 * @deprecated use {@link #getConfigByPolicyName(String policyName, UUID requestID)} Instead.
+	 * @throws PolicyConfigException PolicyConfig Exception
+	 * @deprecated use {@link #getConfig(ConfigRequestParameters configRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfigByPolicyName(String policyName) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.policyName(policyName,(UUID)null);
-		return policyConfig;	
+		return getConfig(setConfigRequestParameters(policyName, null, null, null, null));
 	}
 	
 	/**
@@ -62,13 +112,12 @@
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration. 
-	 * @throws PolicyConfigException
-	 * @deprecated use {@link #getConfigByPolicyName(String policyName, UUID requestID)} Instead.
+	 * @throws PolicyConfigException PolicyConfig Exception
+	 * @deprecated use {@link #getConfig(ConfigRequestParameters configRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfigByPolicyName(String policyName, UUID requestID) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.policyName(policyName,requestID);
-		return policyConfig;	
+		return getConfig(setConfigRequestParameters(policyName, null, null, null, requestID));	
 	}
 	
 	/**
@@ -76,13 +125,12 @@
 	 * 
 	 * @param eCOMPComponentName the <code>String</code> format of the eCOMPComponentName whose configuration is required. 
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration.
-	 * @throws PolicyConfigException 
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,(UUID)null);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, null, null, null));
 	}
 	
 	/**
@@ -92,13 +140,12 @@
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration.
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
-	 * @throws PolicyConfigException 
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName, UUID requestID) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,requestID);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, null, null, requestID));
 	}
 	
 	/**
@@ -109,13 +156,12 @@
 	 * @param eCOMPComponentName the <code>String</code> format of the eCOMPComponentName whose configuration is required.
 	 * @param configName the <code>String</code> format of the configurationName whose configuration is required.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration. 
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName, String configName) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,configName,(UUID)null);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, configName, null, null));
 	}
 	
 	/**
@@ -128,13 +174,12 @@
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration. 
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName, String configName, UUID requestID) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,configName,requestID);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, configName, null, requestID));
 	}
 	
 	/**
@@ -146,13 +191,12 @@
 	 * @param configName the <code>String</code> format of the configurationName whose configuration is required.
 	 * @param configAttributes the <code>Map</code> of <code>String,String</code> format of the configuration attributes which are required.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration.
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName, String configName, Map<String, String> configAttributes) throws PolicyConfigException{
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,configName,configAttributes,(UUID)null);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, configName, configAttributes, null));
 	}
 	
 	/**
@@ -166,13 +210,12 @@
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration.
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 * @deprecated use {@link #getConfig(ConfigRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyConfig> getConfig(String eCOMPComponentName, String configName, Map<String, String> configAttributes, UUID requestID) throws PolicyConfigException{
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(eCOMPComponentName,configName,configAttributes,requestID);
-		return policyConfig;
+		return getConfig(setConfigRequestParameters(null, eCOMPComponentName, configName, configAttributes, requestID));
 	}
 	
 	/**
@@ -181,11 +224,10 @@
 	 * 
 	 * @param configRequestParameters {@link org.openecomp.policy.api.ConfigRequestParameters} which represents the Config policy request parameters. 
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyConfig} which has the configuration.
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 */
 	public Collection<PolicyConfig> getConfig(ConfigRequestParameters configRequestParameters)  throws PolicyConfigException{
-		Collection<PolicyConfig> policyConfig = stdPolicyEngine.config(configRequestParameters);
-		return policyConfig;
+		return stdPolicyEngine.getConfig(configRequestParameters);
 	}
 	
 	/**
@@ -194,11 +236,10 @@
 	 * 
 	 * @param configRequestParameters {@link org.openecomp.policy.api.ConfigRequestParameters} which represents the List Policy request parameters. 
 	 * @return <code>Collection</code> of <code>String</code> which returns the list of policies.
-	 * @throws PolicyConfigException
+	 * @throws PolicyConfigException PolicyConfig Exception
 	 */
 	public Collection<String> listConfig(ConfigRequestParameters listPolicyRequestParameters)  throws PolicyConfigException{
-		Collection<String> policyList = stdPolicyEngine.listConfig(listPolicyRequestParameters);
-		return policyList;
+		return stdPolicyEngine.listConfig(listPolicyRequestParameters);
 	}
 	
 	
@@ -207,13 +248,12 @@
 	 * 
 	 * @param eventAttributes the <code>Map</code> of <code>String,String</code> format of the eventAttributes that must contain the event ID and values.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyResponse} which has the Response. 
-	 * @throws PolicyEventException
+	 * @throws PolicyEventException PolicyEvent Exception
 	 * @deprecated use {@link #sendEvent(EventRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyResponse> sendEvent(Map<String, String> eventAttributes) throws PolicyEventException {
-		Collection<PolicyResponse> policyResponse = stdPolicyEngine.event(eventAttributes, (UUID) null);
-		return policyResponse;
+		return stdPolicyEngine.sendEvent(eventAttributes, (UUID) null);
 	}
 	
 	/**
@@ -223,13 +263,12 @@
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyResponse} which has the Response. 
-	 * @throws PolicyEventException
+	 * @throws PolicyEventException PolicyEvent Exception
 	 * @deprecated use {@link #sendEvent(EventRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public Collection<PolicyResponse> sendEvent(Map<String, String> eventAttributes, UUID requestID) throws PolicyEventException {
-		Collection<PolicyResponse> policyResponse = stdPolicyEngine.event(eventAttributes, requestID);
-		return policyResponse;
+		return stdPolicyEngine.sendEvent(eventAttributes, requestID);
 	}
 	
 	/**
@@ -237,11 +276,10 @@
 	 * 
 	 * @param eventRequestParameters {@link org.openecomp.policy.api.EventRequestParameters} which represents the Event Request Parameters. 
 	 * @return <code>Collection</code> of {@link org.openecomp.policy.api.PolicyResponse} which has the Response.
-	 * @throws PolicyEventException
+	 * @throws PolicyEventException PolicyEvent Exception
 	 */
 	public Collection<PolicyResponse> sendEvent(EventRequestParameters eventRequestParameters) throws PolicyEventException {
-		Collection<PolicyResponse> policyResponse = stdPolicyEngine.event(eventRequestParameters);
-		return policyResponse;
+		return stdPolicyEngine.sendEvent(eventRequestParameters);
 	}
 	
 	/**
@@ -250,13 +288,12 @@
 	 * @param eCOMPComponentName the <code>String</code> format of the eCOMPComponentName whose Decision is required.
 	 * @param decisionAttributes the <code>Map</code> of <code>String,String</code> format of the decisionAttributes that must contain the ID and values.
 	 * @return {@link org.openecomp.policy.api.DecisionResponse} which has the Decision. 
-	 * @throws PolicyDecisionException
+	 * @throws PolicyDecisionException PolicyDecision Exception
 	 * @deprecated use {@link #getDecision(DecisionRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public DecisionResponse getDecision(String eCOMPComponentName, Map<String,String> decisionAttributes) throws PolicyDecisionException {
-		DecisionResponse policyDecision = stdPolicyEngine.decide(eCOMPComponentName, decisionAttributes, null);
-		return policyDecision;
+		return stdPolicyEngine.getDecision(eCOMPComponentName, decisionAttributes, null);
 	}
 	
 	/**
@@ -267,13 +304,12 @@
 	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
 	 * A different request ID should be passed for each request.
 	 * @return {@link org.openecomp.policy.api.DecisionResponse} which has the Decision. 
-	 * @throws PolicyDecisionException
+	 * @throws PolicyDecisionException PolicyDecision Exception
 	 * @deprecated use {@link #getDecision(DecisionRequestParameters)} Instead.
 	 */
 	@Deprecated
 	public DecisionResponse getDecision(String eCOMPComponentName, Map<String,String> decisionAttributes, UUID requestID) throws PolicyDecisionException {
-		DecisionResponse policyDecision = stdPolicyEngine.decide(eCOMPComponentName, decisionAttributes, requestID);
-		return policyDecision;
+		return stdPolicyEngine.getDecision(eCOMPComponentName, decisionAttributes, requestID);
 	}
 	
 	/**
@@ -281,11 +317,228 @@
 	 * 
 	 * @param decisionRequestParameters {@link org.openecomp.policy.api.DecisionRequestParameters} which represents the Decision Request Parameters.
 	 * @return {@link org.openecomp.policy.api.DecisionResponse} which has the Decision.
-	 * @throws PolicyDecisionException
+	 * @throws PolicyDecisionException PolicyDecision Exception
 	 */
 	public DecisionResponse getDecision(DecisionRequestParameters decisionRequestParameters) throws PolicyDecisionException {
-		DecisionResponse policyDecision = stdPolicyEngine.decide(decisionRequestParameters);
-		return policyDecision;
+		return stdPolicyEngine.getDecision(decisionRequestParameters);
+	}
+	
+	/**
+	 * Retrieves the count of policies on the PAP, PDP, and Policy Engine as a whole
+	 * 
+	 * @param parameters {@link com.att.labs.ecomp.policy.api.MetricsRequestParameters} which represents the Parameters required to get the Policy Metrics 
+	 * @return {@link com.att.labs.ecomp.policy.api.MetricsResponse} which consists of the response related to getMetrics Request. 
+	 * @throws PolicyException PolicyException related to the operation	 
+	 * 
+	 * */
+	public MetricsResponse getMetrics(MetricsRequestParameters parameters) throws PolicyException {
+		return stdPolicyEngine.getMetrics(parameters);
+	}
+	
+	/**
+	 * Creates a Config Policy based on given arguments
+	 * @param policyName the <code>String</code> format of the Policy Name
+	 * @param policyDescription the <code>String</code> format of the Policy Description
+	 * @param ecompName the <code>String</code> format of the ECOMP Name
+	 * @param configName the <code>String</code> format of the Config Name
+	 * @param configAttributes the <code>List</code> the <code>Map</code> Attributes that must contain the key and value.
+	 * @param configType the <code>String</code> format of the Config Type
+	 * @param body the <code>String</code> format of the Policy Body
+	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
+	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
+	 * A different request ID should be passed for each request.
+	 * @param riskLevel the <code>String</code> value of risk Level. 
+	 * @param riskType the <code>String</code> value of risk Type. 
+	 * @param guard the <code>String</code> value of guard. 
+	 * @param ttlDate the <code>String</code> value of time to live Date. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 * @return <code>String</code> format of response
+	 * @deprecated use {@link #createPolicy(PolicyParameters)} Instead.
+	 */
+	@Deprecated
+	public String createConfigPolicy(String policyName, String policyDescription, String ecompName, String configName, 
+												Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
+												String riskLevel, String riskType, String guard, String ttlDate) throws PolicyException {
+		return stdPolicyEngine.createUpdateConfigPolicy(policyName, policyDescription, ecompName, configName, 
+				configAttributes, configType, body, policyScope, requestID,
+				riskLevel, riskType, guard, ttlDate, false);
+	}
+	
+	/**
+	 * Creates a Config Policy based on given arguments
+	 * @param policyName the <code>String</code> format of the Policy Name
+	 * @param policyDescription the <code>String</code> format of the Policy Description
+	 * @param ecompName the <code>String</code> format of the ECOMP Name
+	 * @param configName the <code>String</code> format of the Config Name
+	 * @param configAttributes the <code>List</code> the <code>Map</code> Attributes that must contain the key and value.
+	 * @param configType the <code>String</code> format of the Config Type
+	 * @param body the <code>String</code> format of the Policy Body
+	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
+	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
+	 * A different request ID should be passed for each request.
+	 * @param riskLevel the <code>String</code> value of risk Level. 
+	 * @param riskType the <code>String</code> value of risk Type. 
+	 * @param guard the <code>String</code> value of guard. 
+	 * @param ttlDate the <code>String</code> value of time to live Date. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 * @return <code>String</code> format of response
+	 * @deprecated use {@link #updatePolicy(PolicyParameters)} Instead.
+	 */
+	@Deprecated
+	public String updateConfigPolicy(String policyName, String policyDescription, String ecompName, String configName, 
+												Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
+												String riskLevel, String riskType, String guard, String ttlDate) throws PolicyException {
+		return stdPolicyEngine.createUpdateConfigPolicy(policyName, policyDescription, ecompName, configName, 
+				configAttributes, configType, body, policyScope, requestID,riskLevel, riskType, guard, ttlDate, true);
+	}
+	
+	/**
+	 * Creates a Config Firewall Policy based on given arguments
+	 * @param policyName the <code>String</code> format of the Policy Name
+	 * @param firewallJson the <code>JsonObject</code> representation of the Firewall Rules List
+	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
+	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
+	 * A different request ID should be passed for each request.
+	 * @param riskLevel the <code>String</code> value of risk Level. 
+	 * @param riskType the <code>String</code> value of risk Type. 
+	 * @param guard the <code>String</code> value of guard. 
+	 * @param ttlDate the <code>String</code> value of time to live Date. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 * @return <code>String</code> format of response.
+	 * @deprecated use {@link #createPolicy(PolicyParameters)} Instead.
+	 */
+	@Deprecated
+	public String createConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate) throws PolicyException {
+		return stdPolicyEngine.createUpdateConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID,riskLevel, 
+				riskType, guard, ttlDate, false);
+	}
+	
+	/**
+	 * Updates a Config Firewall Policy based on given arguments
+	 * @param policyName the <code>String</code> format of the Policy Name
+	 * @param firewallJson the <code>JsonObject</code> representation of the Firewall Rules List
+	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
+	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
+	 * A different request ID should be passed for each request.
+	 * @param riskLevel the <code>String</code> value of risk Level. 
+	 * @param riskType the <code>String</code> value of risk Type. 
+	 * @param guard the <code>String</code> value of guard. 
+	 * @param ttlDate the <code>String</code> value of time to live Date. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 * @return <code>String</code> format of response. 
+	 * @deprecated use {@link #updatePolicy(PolicyParameters)} Instead.
+	 */
+	@Deprecated
+	public String updateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate) throws PolicyException {
+		return stdPolicyEngine.createUpdateConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID,riskLevel, riskType, guard, ttlDate, true);
+	}
+	
+	/**
+	 * Retrieves Dictionary Items for a specified dictionary
+	 * 
+	 * @param parameters {@link org.openecomp.policy.api.DictionaryParameters} which represents the Dictionary Parameters required to create a Dictionary Item. 
+	 * @return {@link org.openecomp.policy.api.DictionaryResponse} which consists of the response related to create dictionary item Request. 
+	 * @throws PolicyException PolicyException related to the operation	 
+	 * 
+	 * */
+	public DictionaryResponse getDictionaryItem(DictionaryParameters parameters) throws PolicyException {
+		return stdPolicyEngine.getDictionaryItem(parameters);
+	}
+	
+	/**
+	 * Creates a Dictionary Item based on given Dictionary Parameters
+	 * 
+	 * @param parameters {@link org.openecomp.policy.api.DictionaryParameters} which represents the Dictionary Parameters required to create a Dictionary Item. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create dictionary item Request. 
+	 * @throws PolicyException  PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws PolicyException {
+		return stdPolicyEngine.createDictionaryItem(parameters);
+	}
+	
+	/**
+	 * Updates a Dictionary Item based on given Dictionary Parameters
+	 * 
+	 * @param  parameters {@link org.openecomp.policy.api.DictionaryParameters} which represents the Dictionary Parameters required to update a Dictionary Item. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to update dictionary item Request. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse updateDictionaryItem(DictionaryParameters parameters) throws PolicyException {
+		return stdPolicyEngine.updateDictionaryItem(parameters);
+	}
+	
+	/**
+	 * Creates a Policy based on given Policy Parameters. 
+	 * 
+	 * @param policyParameters {@link org.openecomp.policy.api.PolicyParameters} which represents the Policy Parameters required to create a Policy. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create policy Request. 
+	 * @throws PolicyException  PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws PolicyException {
+		return stdPolicyEngine.createPolicy(policyParameters);
+	}
+	
+	/**
+	 * Update Policy based on given Policy Parameters. 
+	 * 
+	 * @param policyParameters {@link org.openecomp.policy.api.PolicyParameters} which represents the Policy Parameters required to update a Policy. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create policy Request. 
+	 * @throws PolicyException  PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws PolicyException {
+		return stdPolicyEngine.updatePolicy(policyParameters);
+	}
+	
+	/**
+	 * Pushes the specified policy to the PDP Group. If no PDP group is selected default is used. 
+	 * 
+	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy is located
+	 * @param policyName the <code>String</code> format of the Policy Name being pushed. 
+	 * @param policyType the <code>String</code> format of the Policy Type which is being pushed.  
+	 * @param pdpGroup the <code>String</code> format of the PDP Group name to which the policy needs to be pushed to. 
+	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
+	 * @return <code>String</code> format of the response related to the push Policy Request. 
+	 * @throws PolicyException  PolicyException related to the operation. 
+	 * @deprecated use {@link #pushPolicy(PushPolicyParameters)} instead. 
+	 */
+	@Deprecated
+	public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID) throws PolicyException {
+		return stdPolicyEngine.pushPolicy(policyScope, policyName, policyType, pdpGroup, requestID);
+	}
+	
+	/**
+	 * Pushes the specified policy to the PDP Group. If no PDP group is selected default is used. 
+	 * 
+	 * @param pushPolicyParameters {@link org.openecomp.policy.api.PushPolicyParameters} which represents the Push Policy parameters required to push a policy. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to the push Policy Request. 
+	 * @throws PolicyException  PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws PolicyException {
+		return stdPolicyEngine.pushPolicy(pushPolicyParameters);
+	}
+	
+	/**
+	 * Deletes the specified policy from the PAP or PDP.
+	 * 
+	 * @param deletePolicyParameters {@link org.openecomp.policy.api.DeletePolicyParameters} which represents the Delete Policy parameters to delete a policy.
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to the Delete Policy Request.
+	 * @throws PolicyException PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse deletePolicy(DeletePolicyParameters deletePolicyParameters) throws PolicyException {
+		return stdPolicyEngine.deletePolicy(deletePolicyParameters);
+	}
+	
+	/**
+	 * Creates a new Policy Service based on given Service Parameters. 
+	 * 
+	 * @param importParameters {@link org.openecomp.policy.api.ImportParameters} which represents the Service Parameters required to create a Policy Service. 
+	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create import Service. 
+	 * @throws PolicyException PolicyException related to the operation. 
+	 */
+	public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws PolicyException {
+		return stdPolicyEngine.policyEngineImport(importParameters);
 	}
 	
 	/**
@@ -316,6 +569,7 @@
 		this.scheme = scheme;
 		stdPolicyEngine.setScheme(this.scheme);
 	}
+	
 	/**
 	 * Gets the <code>PDPNotification</code> if there is one exists. This is used for Polling Patterns. 
 	 * 
@@ -326,250 +580,23 @@
 	}
 	
 	/**
-	 * Creates a Config Policy based on given arguments
-	 * @param policyName the <code>String</code> format of the Policy Name
-	 * @param policyDescription the <code>String</code> format of the Policy Description
-	 * @param ecompName the <code>String</code> format of the ECOMP Name
-	 * @param configName the <code>String</code> format of the Config Name
-	 * @param configAttributes the <code>List</code> the <code>Map</code> Attributes that must contain the key and value.
-	 * @param configType the <code>String</code> format of the Config Type
-	 * @param body the <code>String</code> format of the Policy Body
-	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
-	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
-	 * A different request ID should be passed for each request.
-	 * @throws Exception 
-	 * @return <code>String</code> format of response
-	 * @deprecated use {@link #createPolicy(PolicyParameters)} Instead.
+	 * setClientKey allows the client to use their own implementation logic for Password Protection 
+	 * and will be used to set the clear text password, this will be used while making Requests. 
+	 *   
+	 * @param clientKey depicts String format of Password/ Client_Key.  
 	 */
-	@Deprecated
-	public String createConfigPolicy(String policyName, String policyDescription, String ecompName, String configName, 
-												Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
-												String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = stdPolicyEngine.createConfigPolicy(policyName, policyDescription, ecompName, configName, 
-																configAttributes, configType, body, policyScope, requestID,
-																riskLevel, riskType, guard, ttlDate);
-		
-		return response;
-		
+	public void setClientKey(String clientKey){
+		stdPolicyEngine.setClientKey(clientKey);
 	}
 	
-	/**
-	 * Creates a Config Policy based on given arguments
-	 * @param policyName the <code>String</code> format of the Policy Name
-	 * @param policyDescription the <code>String</code> format of the Policy Description
-	 * @param ecompName the <code>String</code> format of the ECOMP Name
-	 * @param configName the <code>String</code> format of the Config Name
-	 * @param configAttributes the <code>List</code> the <code>Map</code> Attributes that must contain the key and value.
-	 * @param configType the <code>String</code> format of the Config Type
-	 * @param body the <code>String</code> format of the Policy Body
-	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
-	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
-	 * A different request ID should be passed for each request.
-	 * @throws Exception 
-	 * @return <code>String</code> format of response
-	 * @deprecated use {@link #updatePolicy(PolicyParameters)} Instead.
-	 */
-	@Deprecated
-	public String updateConfigPolicy(String policyName, String policyDescription, String ecompName, String configName, 
-												Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
-												String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = stdPolicyEngine.updateConfigPolicy(policyName, policyDescription, ecompName, configName, 
-																configAttributes, configType, body, policyScope, requestID,riskLevel, riskType, guard, ttlDate);
-		
-		return response;
-		
+	// Internal Setter Method to help build configRequestParameters.
+	private ConfigRequestParameters setConfigRequestParameters(String policyName, String eCOMPComponentName, String configName, Map<String, String> configAttributes, UUID requestID){
+		ConfigRequestParameters configRequestParameters = new ConfigRequestParameters();
+		configRequestParameters.setPolicyName(policyName);
+		configRequestParameters.setEcompName(eCOMPComponentName);
+		configRequestParameters.setConfigName(configName);
+		configRequestParameters.setConfigAttributes(configAttributes);
+		configRequestParameters.setRequestID(requestID);
+		return configRequestParameters;
 	}
-	
-	/**
-	 * Creates a Config Firewall Policy based on given arguments
-	 * @param policyName the <code>String</code> format of the Policy Name
-	 * @param firewallJson the <code>JsonObject</code> representation of the Firewall Rules List
-	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
-	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
-	 * A different request ID should be passed for each request.
-	 * @throws Exception 
-	 * @return <code>String</code> format of response.
-	 * @deprecated use {@link #createPolicy(PolicyParameters)} Instead.
-	 */
-	@Deprecated
-	public String createConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = stdPolicyEngine.createConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID,riskLevel, 
-				riskType, guard, ttlDate);
-		
-		return response;
-		
-	}
-	
-	/**
-	 * Updates a Config Firewall Policy based on given arguments
-	 * @param policyName the <code>String</code> format of the Policy Name
-	 * @param firewallJson the <code>JsonObject</code> representation of the Firewall Rules List
-	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy will be created and stored
-	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
-	 * A different request ID should be passed for each request.
-	 * @throws Exception 
-	 * @return <code>String</code> format of response. 
-	 * @deprecated use {@link #updatePolicy(PolicyParameters)} Instead.
-	 */
-	@Deprecated
-	public String updateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = stdPolicyEngine.updateConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID,riskLevel, riskType, guard, ttlDate);
-		
-		return response;
-		
-	}
-	
-	/**
-	 * Creates a Dictionary Item based on given Dictionary Parameters
-	 * 
-	 * @param policyParameters {@link org.openecomp.policy.api.DictionaryParameters} which represents the Dictionary Parameters required to create a Dictionary Item. 
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create dictionary item Request. 
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.createDictionaryItem(parameters);
-		return response;
-	}
-	
-	/**
-	 * Creates a Policy based on given Policy Parameters. 
-	 * 
-	 * @param policyParameters {@link org.openecomp.policy.api.PolicyParameters} which represents the Policy Parameters required to create a Policy. 
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create policy Request. 
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.createPolicy(policyParameters);
-		return response;
-	}
-	
-	/**
-	 * Update Policy based on given Policy Parameters. 
-	 * 
-	 * @param policyParameters {@link org.openecomp.policy.api.PolicyParameters} which represents the Policy Parameters required to update a Policy. 
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create policy Request. 
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.updatePolicy(policyParameters);
-		return response;
-	}
-	
-	/**
-	 * Pushes the specified policy to the PDP Group. If no PDP group is selected default is used. 
-	 * 
-	 * @param policyScope the <code>String</code> value of the sub scope directory where the policy is located
-	 * @param policyName the <code>String</code> format of the Policy Name being pushed. 
-	 * @param policyType the <code>String</code> format of the Policy Type which is being pushed.  
-	 * @param pdpGroup the <code>String</code> format of the PDP Group name to which the policy needs to be pushed to. 
-	 * @param requestID unique request ID which will be passed throughout the ECOMP components to correlate logging messages.
-	 * @return <code>String</code> format of the response related to the push Policy Request. 
-	 * @throws Exception
-	 * @deprecated use {@link #pushPolicy(PushPolicyParameters)} instead. 
-	 */
-	@Deprecated
-	public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID) throws Exception {
-		
-		String response = stdPolicyEngine.pushPolicy(policyScope, policyName, policyType, pdpGroup, requestID);
-		
-		return response;
-	}
-	
-	/**
-	 * Pushes the specified policy to the PDP Group. If no PDP group is selected default is used. 
-	 * 
-	 * @param pushPolicyParameters {@link org.openecomp.policy.api.PushPolicyParameters} which represents the Push Policy parameters required to push a policy. 
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to the push Policy Request. 
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.pushPolicy(pushPolicyParameters);
-		return response;
-	}
-	
-	/**
-	 * Deletes the specified policy from the PAP or PDP.
-	 * 
-	 * @param deletePolicyParameters {@link org.openecomp.policy.api.DeletePolicyParameters} which represents the Delete Policy parameters to delete a policy.
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to the Delete Policy Request.
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse deletePolicy(DeletePolicyParameters deletePolicyParameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.deletePolicy(deletePolicyParameters);
-		return response;
-	}
-	
-	/**
-	 * PolicyEngine Constructor with <code>String</code> format of propertiesFilePathname
-	 * 
-	 * @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname 
-	 * @throws PolicyEngineException 
-	 */
-	public PolicyEngine(String propertiesFilePathname) throws PolicyEngineException {
-		this.propertyFilePath = propertiesFilePathname ; 
-		this.stdPolicyEngine= new StdPolicyEngine(this.propertyFilePath);
-	}
-	
-	/**
-	 * PolicyEngine Constructor with <code>String</code> format of PropertiesFilePathname, <code>NotificationScheme</code> and <code>NotificationHandler</code>
-	 *  
-	 *  @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname 
-	 *  @param scheme the <code>NotificationScheme</code> of {@link org.openecomp.policy.api.NotificationScheme} which defines the Notification Scheme
-	 *  @param handler the <code>NotificationHandler</code> of {@link org.openecomp.policy.api.NotificationHandler} which defines what should happen when a notification is received.
-	 *  @throws PolicyEngineException 
-	 */
-	public PolicyEngine(String propertiesFilePathname, NotificationScheme scheme, NotificationHandler handler) throws PolicyEngineException {
-		this.propertyFilePath = propertiesFilePathname ;
-		this.scheme = scheme;
-		this.handler = handler;
-		this.stdPolicyEngine= new StdPolicyEngine(this.propertyFilePath,this.scheme,this.handler);
-	}
-	
-	/**
-	 * Creates a new Policy Service based on given Service Parameters. 
-	 * 
-	 * @param importParameters {@link org.openecomp.policy.api.ImportParameters} which represents the Service Parameters required to create a Policy Service. 
-	 * @return {@link org.openecomp.policy.api.PolicyChangeResponse} which consists of the response related to create import Service. 
-	 * @throws Exception
-	 */
-	public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws Exception {
-		PolicyChangeResponse response = stdPolicyEngine.policyEngineImport(importParameters);
-		return response;
-	}
-	
-	/**
-	 * PolicyEngine Constructor with <code>String</code> format of PropertiesFilePathname and <code>NotificationScheme</code>
-	 * 
-	 * @param propertiesFilePathname the <code>String</code> format of the propertiesFilePathname
-	 * @param scheme the <code>NotificationScheme</code> of {@link org.openecomp.policy.api.NotificationScheme} which defines the Notification Scheme
-	 * @throws PolicyEngineException 
-	 */
-	public PolicyEngine(String propertiesFilePathname, NotificationScheme scheme) throws PolicyEngineException{
-		this.propertyFilePath = propertiesFilePathname;
-		this.scheme = scheme;
-		this.stdPolicyEngine = new StdPolicyEngine(this.propertyFilePath, this.scheme);
-	}
-	/**
-	 * PolicyEngine Constructor with no parameters.
-	 *//*
-	public PolicyEngine(){
-		
-	}
-	public void createFirewallPolicy(String filterName, String termName, String preIPSource, String preIPDest, 
-										String sourcePort, String destPort, String Port, String protocol, String direction, String action ) throws PolicyDecisionException {
-		stdPolicyEngine.createFirewallPolicy(filterName, termName, preIPSource, preIPDest, sourcePort, destPort, Port,
-												protocol, direction, action);
-	}
-	
-	public void updateFirewallPolicy(String filterName, String termName, String preIPSource, String preIPDest, 
-										String sourcePort, String destPort, String Port, String protocol, String direction, String action ) throws PolicyDecisionException {
-			stdPolicyEngine.updateFirewallPolicy(filterName, termName, preIPSource, preIPDest, sourcePort, destPort, Port,
-													protocol, direction, action);
-	}*/
-}
+}
\ No newline at end of file
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyException.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyException.java
new file mode 100644
index 0000000..f4a99fd
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyException.java
@@ -0,0 +1,29 @@
+package org.openecomp.policy.api;
+
+/**
+ * PolicyException extends <code>Exception</code> to implement exceptions thrown by {@link org.openecomp.policy.api.PolicyEngine}
+ * 
+ * @version 0.1
+ */
+public class PolicyException extends Exception {
+	private static final long serialVersionUID = -5006203722296799708L;
+	
+	public PolicyException() {
+	}
+	
+	public PolicyException(String message) {
+		super(message);
+	}
+	
+	public PolicyException(Throwable cause){
+		super(cause);
+	}
+	
+	public PolicyException(String message, Throwable cause) {
+		super(message, cause);
+	}
+	
+	public PolicyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+	}
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyParameters.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyParameters.java
index 32cd75b..4894088 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyParameters.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyParameters.java
@@ -20,6 +20,7 @@
 
 package org.openecomp.policy.api;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -50,6 +51,8 @@
 	private List<String> dynamicRuleAlgorithmField2;
 	private String priority;
 	private RuleProvider ruleProvider;
+	private String controllerName;
+	private ArrayList<String> dependencyNames;
 	private Date TTLDate;
 	private boolean guard = false;
 	private String riskLevel = "5";
@@ -203,7 +206,9 @@
 	 * @param policyConfigType the {@link org.openecomp.policy.api.PolicyConfigType} Enum format of the Config Type
 	 */
 	public void setPolicyConfigType(PolicyConfigType policyConfigType) {
-		setPolicyClass(PolicyClass.Config);
+		if(policyConfigType!=null){
+	        setPolicyClass(PolicyClass.Config);
+	    }
 		this.policyConfigType = policyConfigType;
 	}
 
@@ -444,7 +449,7 @@
 	/**
 	 * Sets the riskType field of the Policy Parameters. 
 	 * 
-	 * @param guard the <code>String</code> format of the riskType value
+	 * @param riskType the <code>String</code> format of the riskType value
 	 */
 	public void setRiskType(String riskType){
 		this.riskType = riskType;
@@ -494,4 +499,50 @@
 	public Date getTtlDate(){
 		return TTLDate;
 	}
+	
+	/**
+	 * Gets the Controller Name for your policy. 
+	 *  
+	 * @return String format of the controller Name. 
+	 */
+	public String getControllerName() {
+        return controllerName;
+    }
+	
+	/**
+	 * Sets Controller Name for your policy. 
+	 * 
+	 * @param controllerName to identify the controller information for your policy. 
+	 */
+    public void setControllerName(String controllerName) {
+        this.controllerName = controllerName;
+    }
+    
+    /**
+     * Gets Dependency Names for your policy. 
+     * 
+     * @return ArrayList of String(s) format of dependency names.
+     */
+    public ArrayList<String> getDependencyNames() {
+        return dependencyNames;
+    }
+
+    /**
+     * Sets Dependency that your policy is dependent on. 
+     * 
+     * @param dependencyNames ArrayList of String(s). 
+     */
+    public void setDependencyNames(ArrayList<String> dependencyNames) {
+        this.dependencyNames = dependencyNames;
+    }
+	
+	public String toString() {
+		return "PolicyParameters [ policyName=" + policyName + ", policyDescription=" + policyDescription + ", ecompName="+ ecompName 
+				+ ", configName=" + configName + ", attributes=" + attributes + ", configBody=" + configBody 
+				+ ",dynamicRuleAlgorithmLabels=" + dynamicRuleAlgorithmLabels + ",dynamicRuleAlgorithmFunctions=" + dynamicRuleAlgorithmFunctions 
+				+ ",dynamicRuleAlgorithmField1=" + dynamicRuleAlgorithmField1 + ",dynamicRuleAlgorithmField2=" + dynamicRuleAlgorithmField2 
+				+ ", actionPerformer=" + actionPerformer + ", actionAttribute=" + actionAttribute + ", priority=" + priority  
+				+ ", ruleProvider= " + ruleProvider + ", riskLevel= " + riskLevel + ", riskType= " + riskType
+				+ "]";
+	}
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyResponseStatus.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyResponseStatus.java
index a9c3296..84fac73 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyResponseStatus.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyResponseStatus.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of PolicyResponseStatus that can be returned as a part of
  * {@link org.openecomp.policy.api.PolicyResponse}.
@@ -70,4 +72,14 @@
 	public String toString(){
 		return this.name;
 	}
+	
+	@JsonCreator
+    public static PolicyResponseStatus create (String value) {
+        for(PolicyResponseStatus type: values()){
+            if(type.toString().equals(value) || type.equals(PolicyResponseStatus.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyType.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyType.java
index b86f952..a0566e0 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyType.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/PolicyType.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Policy Return Types that can be returned as part of a
  * {@link org.openecomp.policy.api.PolicyConfig}.
@@ -58,4 +60,13 @@
 	public String toString() {
 		return this.name;
 	}
+	@JsonCreator
+    public static PolicyType create (String value) {
+        for(PolicyType type: values()){
+            if(type.toString().equalsIgnoreCase(value)){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }	
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/RuleProvider.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/RuleProvider.java
index 8e92181..e263d5d 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/RuleProvider.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/api/RuleProvider.java
@@ -20,6 +20,8 @@
 
 package org.openecomp.policy.api;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 /**
  * Enumeration of the Attribute Types that is used as a part of
  * {@link org.openecomp.policy.api.PolicyParameters}.
@@ -50,4 +52,14 @@
 	public String toString() {
 		return this.name;
 	}
+	
+	@JsonCreator
+    public static RuleProvider create (String value) {
+        for(RuleProvider type: values()){
+            if(type.toString().equals(value) || type.equals(RuleProvider.valueOf(value))){
+                return type;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
 }
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIConfigResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIConfigResponse.java
new file mode 100644
index 0000000..6645226
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIConfigResponse.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineAPI
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.models;
+
+import java.util.Map;
+
+import org.openecomp.policy.api.PolicyConfigStatus;
+import org.openecomp.policy.api.PolicyType;
+
+public interface APIConfigResponse {
+    public String getPolicyConfigMessage();
+    public PolicyConfigStatus getPolicyConfigStatus();
+    public PolicyType getType(); // PolicyType
+    public String getConfig();
+    public String getPolicyName();
+    public String getPolicyVersion();
+    public Map<String,String> getMatchingConditions();
+    public Map<String,String> getResponseAttributes();
+    public Map<String,String> getProperty();
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIDictionaryResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIDictionaryResponse.java
new file mode 100644
index 0000000..4829bfa
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIDictionaryResponse.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineAPI
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.models;
+
+public class APIDictionaryResponse {
+    private Object dictionaryData;
+    private Object dictionaryJson;
+    private int responseCode;
+    private String responseMessage;
+    public Object getDictionaryData() {
+        return dictionaryData;
+    }
+    public void setDictionaryData(Object dictionaryData) {
+        this.dictionaryData = dictionaryData;
+    }
+    public Object getDictionaryJson() {
+        return dictionaryJson;
+    }
+    public void setDictionaryJson(Object dictionaryJson) {
+        this.dictionaryJson = dictionaryJson;
+    }
+    public int getResponseCode() {
+        return responseCode;
+    }
+    public void setResponseCode(int responseCode) {
+        this.responseCode = responseCode;
+    }
+    public String getResponseMessage() {
+        return responseMessage;
+    }
+    public void setResponseMessage(String responseMessage) {
+        this.responseMessage = responseMessage;
+    }
+    
+    
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIPolicyConfigResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIPolicyConfigResponse.java
new file mode 100644
index 0000000..7be9321
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/models/APIPolicyConfigResponse.java
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineAPI
+ * ================================================================================
+ * 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=========================================================
+ */
+package org.openecomp.policy.models;
+
+import java.util.Map;
+
+import org.openecomp.policy.api.PolicyConfigStatus;
+import org.openecomp.policy.api.PolicyType;
+
+public class APIPolicyConfigResponse implements APIConfigResponse {
+    private String policyConfigMessage;
+    private PolicyConfigStatus policyConfigStatus;
+    private PolicyType type;
+    private String config;
+    private String policyName;
+    private String policyVersion;
+    private Map<String, String> matchingConditions;
+    private Map<String, String> responseAttributes;
+    private Map<String, String> property;
+    public String getConfig() {
+        return config;
+    }
+    public void setConfig(String config) {
+        this.config = config;
+    }
+    public PolicyType getType() {
+        return type;
+    }
+    public void setType(PolicyType type) {
+        this.type = type;
+    }
+    public PolicyConfigStatus getPolicyConfigStatus() {
+        return policyConfigStatus;
+    }
+    public void setPolicyConfigStatus(PolicyConfigStatus policyConfigStatus) {
+        this.policyConfigStatus = policyConfigStatus;
+    }
+    public String getPolicyConfigMessage() {
+        return policyConfigMessage;
+    }
+    public void setPolicyConfigMessage(String policyConfigMessage) {
+        this.policyConfigMessage = policyConfigMessage;
+    }
+    public Map<String, String> getProperty() {
+        return property;
+    }
+    public void setProperty(Map<String, String> property) {
+        this.property = property;
+    }
+    public String getPolicyName(){
+        return policyName;
+    }
+    public void setPolicyName(String policyName){
+        this.policyName = policyName;
+    }
+    public String getPolicyVersion(){
+        return policyVersion;
+    }
+    public void setPolicyVersion(String policyVersion){
+        this.policyVersion = policyVersion;
+    }
+    public Map<String, String> getMatchingConditions(){
+        return matchingConditions;
+    }
+    public void setMatchingConditions(Map<String, String> matchingConditions){
+        this.matchingConditions = matchingConditions;
+    }
+    public void setResponseAttributes(Map<String,String> responseAttributes){
+        this.responseAttributes = responseAttributes;
+    }
+    public Map<String,String> getResponseAttributes(){
+        return responseAttributes;
+    }
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientDMAAP.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientDMAAP.java
new file mode 100644
index 0000000..563cd85
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientDMAAP.java
@@ -0,0 +1,132 @@
+package org.openecomp.policy.std;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.openecomp.policy.api.NotificationHandler;
+import org.openecomp.policy.api.NotificationScheme;
+import org.openecomp.policy.api.NotificationType;
+import org.openecomp.policy.api.PDPNotification;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.utils.BusConsumer;
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+public class AutoClientDMAAP implements Runnable {
+	private static StdPDPNotification notification = null;
+	private static NotificationScheme scheme = null;
+	private static NotificationHandler handler = null;
+	private static String topic = null;
+	private static boolean status = false; 
+	private static Logger logger = FlexLogger.getLogger(AutoClientDMAAP.class.getName());
+	private static String notficatioinType = null;
+	private static BusConsumer dmaapConsumer = null;
+	private static List<String> dmaapList = null; 
+	private static String aafLogin = null;
+	private static String aafPassword = null;
+	public volatile boolean isRunning = false;
+    
+
+	public AutoClientDMAAP(List<String> dmaapList, String topic, String aafLogin, String aafPassword) {
+	       AutoClientDMAAP.topic = topic;
+	       AutoClientDMAAP.dmaapList = dmaapList;
+	       AutoClientDMAAP.aafLogin = aafLogin;
+	       AutoClientDMAAP.aafPassword = aafPassword;
+	}
+
+	public void setAuto(NotificationScheme scheme,
+			NotificationHandler handler) {
+		AutoClientDMAAP.scheme = scheme;
+		AutoClientDMAAP.handler = handler;
+	}
+
+	public static void setScheme(NotificationScheme scheme) {
+		AutoClientDMAAP.scheme = scheme;
+	}
+	
+	public static boolean getStatus(){
+		return AutoClientDMAAP.status;
+	}
+
+	public static String getTopic() {
+		return AutoClientDMAAP.topic;
+	}
+	
+	public static String getNotficationType(){
+		return AutoClientDMAAP.notficatioinType;
+	}
+
+	public synchronized boolean isRunning() {
+		return this.isRunning;
+	}
+	
+	public synchronized void terminate() {
+		this.isRunning = false;
+	}
+	
+	@Override
+	public void run() {
+		synchronized(this) {
+			this.isRunning = true;
+		}
+		String group =  UUID.randomUUID ().toString ();
+		String id = "0";
+
+		// Stop and Start needs to be done.
+		if (scheme != null && handler!=null) {
+			if (scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS) || scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
+					
+				// create a loop to listen for messages from DMaaP server
+				try {
+					dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, topic, aafLogin, aafPassword, group, id, 15*1000, 1000 );
+				} catch (Exception e) {
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e);
+				} 
+				
+				while (this.isRunning() )
+				{
+					try {
+						for ( String msg : dmaapConsumer.fetch () )
+						{		
+							logger.debug("Auto Notification Recieved Message " + msg + " from DMAAP server : " + dmaapList.toString());
+							notification = NotificationUnMarshal.notificationJSON(msg);
+							callHandler();
+						}
+					} catch (Exception e) {
+						logger.debug("Error in processing DMAAP message");
+					}
+
+				}
+				logger.debug("Stopping DMAAP Consumer loop will no longer fetch messages from the servers");
+			}
+		}
+	}
+
+	private static void callHandler() {
+		if (handler != null && scheme != null) {
+			if (scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)) {
+				boolean removed = false, updated = false;
+				if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
+					removed = true;
+				}
+				if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
+					updated = true;
+				}
+				if (removed && updated) {
+					notification.setNotificationType(NotificationType.BOTH);
+				} else if (removed) {
+					notification.setNotificationType(NotificationType.REMOVE);
+				} else if (updated) {
+					notification.setNotificationType(NotificationType.UPDATE);
+				}
+				handler.notificationReceived(notification);
+			} else if (scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
+				PDPNotification newNotification = MatchStore.checkMatch(notification);
+				if (newNotification.getNotificationType() != null) {
+					handler.notificationReceived(newNotification);
+				}
+			}
+		}
+	}
+
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientEnd.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientEnd.java
index 3f4fe0c..9ca544f 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientEnd.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientEnd.java
@@ -122,7 +122,7 @@
 	
 	private static void changeURL(){
 		// Change the PDP if it is not Up. 
-		StdPolicyEngine.rotateList();
+		StdPolicyEngine.rotatePDPList();
 		start(StdPolicyEngine.getPDPURL());
 	}
 
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientUEB.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientUEB.java
index 87bb501..40bd801 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientUEB.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/AutoClientUEB.java
@@ -31,33 +31,42 @@
 import org.openecomp.policy.api.NotificationType;
 import org.openecomp.policy.api.PDPNotification;
 import org.openecomp.policy.std.StdPDPNotification;
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
 
+import com.att.nsa.cambria.client.CambriaClientBuilders;
 import com.att.nsa.cambria.client.CambriaClientFactory;
 import com.att.nsa.cambria.client.CambriaConsumer;
-import org.openecomp.policy.common.logging.flexlogger.*; 
+import com.att.nsa.cambria.client.CambriaClientBuilders.ConsumerBuilder;
 /**
  * Create a UEB Consumer to receive policy update notification.
  * 
  * 
  *
  */
+@SuppressWarnings("deprecation")
 public class AutoClientUEB implements Runnable  {
 	private static StdPDPNotification notification = null;
 	private static NotificationScheme scheme = null;
 	private static NotificationHandler handler = null;
+	private static String topic = null;
 	private static String url = null;
 	private static boolean status = false; 
 	private static Logger logger = FlexLogger.getLogger(AutoClientUEB.class.getName());
 	private static String notficatioinType = null;
 	private static CambriaConsumer CConsumer = null;
-//	private volatile boolean stop = false;
+	private static String apiKey = null;
+	private static String apiSecret = null;
 	private static List<String> uebURLList = null; 
 	public volatile boolean isRunning = false;
     
 
-	public AutoClientUEB(String url, List<String> uebURLList) {
+	public AutoClientUEB(String url, List<String> uebURLList, String apiKey, String apiSecret) {
 	       AutoClientUEB.url = url;
 	       AutoClientUEB.uebURLList = uebURLList;
+	       AutoClientUEB.apiKey = apiKey;
+	       AutoClientUEB.apiKey = apiKey;
 	}
 
 	public void setAuto(NotificationScheme scheme,
@@ -89,7 +98,7 @@
 	public synchronized void terminate() {
 		this.isRunning = false;
 	}
-	@SuppressWarnings("deprecation")
+	
 	@Override
 	public void run() {
 		synchronized(this) {
@@ -97,27 +106,35 @@
 		}
 		String group =  UUID.randomUUID ().toString ();
 		String id = "0";
-		String topic = null;
+		//String topic = null;
 		// Stop and Start needs to be done.
 		if (scheme != null && handler!=null) {
 			if (scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS) || scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
-				//Check if the Notification Type is UEB t				if (notficationType.equals("ueb")){
 				URL aURL;
 				try {
-					aURL = new URL(AutoClientUEB.url);
+					aURL = new URL(AutoClientUEB.topic);
 					topic = aURL.getHost() + aURL.getPort();
 				} catch (MalformedURLException e) {
 					topic = AutoClientUEB.url.replace("[:/]", "");
 				}
-					
+				
 				//TODO  create a loop to listen for messages from UEB cluster
+					
 				try {
-					CConsumer = CambriaClientFactory.createConsumer ( null, uebURLList, topic, group, id, 15*1000, 1000 );
+					//CConsumer = CambriaClientFactory.createConsumer ( null, uebURLList, topic, group, id, 15*1000, 1000 );
+					ConsumerBuilder builder = new CambriaClientBuilders.ConsumerBuilder();
+					builder.knownAs(group, id)
+					.usingHosts(uebURLList)
+					.onTopic(topic)
+					.waitAtServer(15*1000)
+					.receivingAtMost(1000)
+					.authenticatedBy(apiKey, apiSecret);
+					
+					 CConsumer = builder.build();
+					
 				} catch (MalformedURLException e1) {
-					// TODO Auto-generated catch block
 					e1.printStackTrace();
 				} catch (GeneralSecurityException e1) {
-					// TODO Auto-generated catch block
 					e1.printStackTrace();
 				}
 				while (this.isRunning() )
@@ -131,11 +148,11 @@
 						}
 					} catch (Exception e) {
 						// TODO Auto-generated catch block
-						logger.debug("Error in processing UEB message");
+						logger.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Error in processing UEB message" + e.getMessage());
 					}
 
 				}
-				logger.debug("Stopping UEB Consuer loop will not logger fetch messages from the cluser");
+				logger.debug("Stopping UEB Consumer loop will not logger fetch messages from the cluster");
 			}
 		}
 	}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndDMAAP.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndDMAAP.java
new file mode 100644
index 0000000..0e30ada
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndDMAAP.java
@@ -0,0 +1,105 @@
+package org.openecomp.policy.std;
+
+import java.util.List;
+
+import org.json.JSONObject;
+import org.openecomp.policy.api.NotificationScheme;
+import org.openecomp.policy.api.NotificationType;
+import org.openecomp.policy.api.PDPNotification;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+import org.openecomp.policy.utils.BusConsumer;
+import org.openecomp.policy.utils.BusPublisher;
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+public class ManualClientEndDMAAP {
+	private static StdPDPNotification notification = null;
+	private static String resultJson = null;
+	private static Logger logger = FlexLogger.getLogger(ManualClientEndDMAAP.class.getName());
+	private static BusConsumer dmaapConsumer = null;
+	private static String uniquID = null;
+	private static String topic = null;
+	
+
+	public static PDPNotification result(NotificationScheme scheme) {
+		if (resultJson == null || notification == null) {
+			logger.debug("No Result" );
+			return null;
+		} else {
+			if(scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)) {
+				boolean removed = false, updated = false; 
+				if(notification.getRemovedPolicies()!=null && !notification.getRemovedPolicies().isEmpty()){
+					removed = true;
+				}
+				if(notification.getLoadedPolicies()!=null && !notification.getLoadedPolicies().isEmpty()){
+					updated = true;
+				}
+				if(removed && updated) {
+					notification.setNotificationType(NotificationType.BOTH);
+				}else if(removed){
+					notification.setNotificationType(NotificationType.REMOVE);
+				}else if(updated){
+					notification.setNotificationType(NotificationType.UPDATE);
+				}
+				return notification;
+			}else if(scheme.equals(NotificationScheme.MANUAL_NOTIFICATIONS)) {
+				return MatchStore.checkMatch(notification);
+			}else {
+				return null;
+			}
+		}
+	}
+
+	private static void publishMessage(String pubTopic, String uniqueID, List<String> dmaapList, String aafLogin, String aafPassword) {
+        BusPublisher pub = null;
+		try {
+			pub = new BusPublisher.DmaapPublisherWrapper(dmaapList, topic, aafLogin, aafPassword);
+			final JSONObject msg1 = new JSONObject (); 
+	        msg1.put ( "JSON", "DMaaP Update Request UID=" + uniqueID);  
+	        pub.send ( "MyPartitionKey", msg1.toString () );
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Publisher: ", e);
+		}
+        pub.close (); 
+	}
+
+	//NOTE:  should be able to remove this for DMAAP since we will not be creating topics dynamically
+	public static void createTopic (String topic, String uniquID, List<String> dmaapList, String aafLogin, String aafPassword){
+		ManualClientEndDMAAP.topic = topic;
+		publishMessage(topic, uniquID, dmaapList, aafLogin, aafPassword);
+	}
+	
+	
+	public static void start(List<String> dmaapList, String topic, String aafLogin, String aafPassword, String uniqueID) {
+		
+		ManualClientEndDMAAP.uniquID = uniqueID;
+		ManualClientEndDMAAP.topic = topic;
+		
+		String id = "0";
+		
+		try {
+			dmaapConsumer = new BusConsumer.DmaapConsumerWrapper(dmaapList, topic, aafLogin, aafPassword, "clientGroup", id, 15*1000, 1000);
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to create DMaaP Consumer: ", e);
+		}
+		
+		int count = 1;
+		while (count < 4) {
+				publishMessage(topic, uniquID, dmaapList, aafLogin, aafPassword);
+				try {
+					for ( String msg : dmaapConsumer.fetch () )
+					{	
+						logger.debug("Manual Notification Recieved Message " + msg + " from DMaaP server : " + dmaapList.toString());
+						resultJson = msg;
+						if (!msg.contains("DMaaP Update")){
+							notification = NotificationUnMarshal.notificationJSON(msg);
+							count = 4;
+						}
+					}
+				}catch (Exception e) {
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to fetch messages from DMaaP servers: ", e);
+				} 
+				count++;
+			}		
+	}
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndUEB.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndUEB.java
index b1962bc..398e8d5 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndUEB.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/ManualClientEndUEB.java
@@ -22,36 +22,33 @@
 
 import java.io.IOException;
 import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.GeneralSecurityException;
 import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
 
-//import org.apache.log4j.Logger;
 import org.json.JSONObject;
 import org.openecomp.policy.api.NotificationScheme;
 import org.openecomp.policy.api.NotificationType;
 import org.openecomp.policy.api.PDPNotification;
-import org.openecomp.policy.std.StdPDPNotification;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
 
 import com.att.nsa.cambria.client.CambriaClientFactory;
 import com.att.nsa.cambria.client.CambriaConsumer;
-import com.att.nsa.cambria.client.CambriaPublisher;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import org.openecomp.policy.common.logging.flexlogger.*; 
+import com.att.nsa.cambria.client.CambriaPublisher; 
 
 
+@SuppressWarnings("deprecation")
 public class ManualClientEndUEB {
 	private static StdPDPNotification notification = null;
 	private static String resultJson = null;
 	private static Logger logger = FlexLogger.getLogger(ManualClientEndUEB.class.getName());
 	private static CambriaConsumer CConsumer = null;
+	@SuppressWarnings("unused")
 	private static List<String> uebURLList = null; 
+	@SuppressWarnings("unused")
 	private static boolean messageNotReceived = false;
+	@SuppressWarnings("unused")
 	private static String url = null;
 	private static String uniquID = null;
 	private static String topic = null;
@@ -94,10 +91,8 @@
 		try {
 			pub = CambriaClientFactory.createSimplePublisher(null, UEBlist, pubTopic);
 		} catch (MalformedURLException e1) {
-			// TODO Auto-generated catch block
 			e1.printStackTrace();
 		} catch (GeneralSecurityException e1) {
-			// TODO Auto-generated catch block
 			e1.printStackTrace();
 		}
         final JSONObject msg1 = new JSONObject (); 
@@ -107,7 +102,6 @@
         try {
 			pub.send ( "MyPartitionKey", msg1.toString () );
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 		} 
         pub.close (); 
@@ -142,10 +136,8 @@
 		try {
 			CConsumer = CambriaClientFactory.createConsumer ( null, uebURLList, topic + uniquID, "clientGroup", id, 15*1000, 1000 );
 		} catch (MalformedURLException e1) {
-			// TODO Auto-generated catch block
 			e1.printStackTrace();
 		} catch (GeneralSecurityException e1) {
-			// TODO Auto-generated catch block
 			e1.printStackTrace();
 		}		
 		int count = 1;
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/MatchStore.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/MatchStore.java
index 2c06b9a..ac3c9e9 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/MatchStore.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/MatchStore.java
@@ -101,7 +101,7 @@
 		}
 	}
 	
-	//TODO Logic changes for Requested Policies notifications.. 
+	//Logic changes for Requested Policies notifications.. 
 	public static PDPNotification checkMatch(PDPNotification oldNotification) {
 		boolean removed = false, updated = false;
 		if(oldNotification==null){
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdDictionaryResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdDictionaryResponse.java
new file mode 100644
index 0000000..74eebc3
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdDictionaryResponse.java
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineAPI
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.std;
+
+import java.util.Map;
+
+import javax.json.JsonObject;
+
+import org.openecomp.policy.api.DictionaryResponse;
+
+public class StdDictionaryResponse implements DictionaryResponse {
+	private String dictionaryMessage;
+	private JsonObject dictionaryJson;
+	private Map<String,String> dictionaryData; 
+	private int responseCode;
+	
+	@Override
+	public String getResponseMessage() {
+		return dictionaryMessage;
+	}
+
+	@Override
+	public JsonObject getDictionaryJson() {
+		return dictionaryJson;
+	}
+
+	@Override
+	public Map<String, String> getDictionaryData() {
+		return dictionaryData;
+	}
+
+	@Override
+	public int getResponseCode() {
+		return responseCode;
+	}
+
+	public void setResponseMessage(String dictionaryMessage) {
+		this.dictionaryMessage = dictionaryMessage;
+	}
+
+	public void setDictionaryJson(JsonObject dictionaryJson) {
+		this.dictionaryJson = dictionaryJson;
+	}
+
+	public void setDictionaryData(Map<String, String> dictionaryData) {
+		this.dictionaryData = dictionaryData;
+	}
+
+	public void setResponseCode(int responseCode) {
+		this.responseCode = responseCode;
+	}
+	
+	
+
+}
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdMetricsResponse.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdMetricsResponse.java
new file mode 100644
index 0000000..8c89e4a
--- /dev/null
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdMetricsResponse.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineAPI
+ * ================================================================================
+ * 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=========================================================
+ */
+
+package org.openecomp.policy.std;
+
+import org.openecomp.policy.api.MetricsResponse;
+
+public class StdMetricsResponse implements MetricsResponse {
+	private String responseMessage;
+	private int pdpMetrics;
+	private int papMetrics;
+	private int metricsTotal;
+	private int responseCode;
+	
+	@Override
+	public String getResponseMessage() {
+		return responseMessage;
+	}
+
+	@Override
+	public int getResponseCode() {
+		return responseCode;
+	}
+
+	@Override
+	public int getPapMetrics() {
+		return papMetrics;
+	}
+
+	@Override
+	public int getPdpMetrics() {
+		return pdpMetrics;
+	}
+
+	@Override
+	public int getMetricsTotal() {
+		metricsTotal = papMetrics + pdpMetrics;
+		return metricsTotal;
+	}
+
+	public void setResponseMessage(String responseMessage) {
+		this.responseMessage = responseMessage;
+	}
+
+	public void setPdpMetrics(int pdpMetrics) {
+		this.pdpMetrics = pdpMetrics;
+	}
+
+	public void setPapMetrics(int papMetrics) {
+		this.papMetrics = papMetrics;
+	}
+
+	public void setMetricsTotal(int metricsTotal) {
+		this.metricsTotal = metricsTotal;
+	}
+
+	public void setResponseCode(int responseCode) {
+		this.responseCode = responseCode;
+	}
+
+}
\ No newline at end of file
diff --git a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdPolicyEngine.java b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdPolicyEngine.java
index 11e4e4f..abe5ee7 100644
--- a/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdPolicyEngine.java
+++ b/PolicyEngineAPI/src/main/java/org/openecomp/policy/std/StdPolicyEngine.java
@@ -21,57 +21,47 @@
 
 package org.openecomp.policy.std;
 
-import java.io.ByteArrayInputStream;
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.StringReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URI;
+import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 
 import javax.json.Json;
-import javax.json.JsonArrayBuilder;
 import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
 import javax.json.JsonReader;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.http.entity.ContentType;
-//import org.apache.log4j.Logger;
-import org.json.JSONObject;
 import org.openecomp.policy.api.AttributeType;
 import org.openecomp.policy.api.ConfigRequestParameters;
 import org.openecomp.policy.api.DecisionRequestParameters;
 import org.openecomp.policy.api.DecisionResponse;
 import org.openecomp.policy.api.DeletePolicyParameters;
 import org.openecomp.policy.api.DictionaryParameters;
+import org.openecomp.policy.api.DictionaryResponse;
 import org.openecomp.policy.api.EventRequestParameters;
 import org.openecomp.policy.api.ImportParameters;
+import org.openecomp.policy.api.MetricsRequestParameters;
+import org.openecomp.policy.api.MetricsResponse;
 import org.openecomp.policy.api.NotificationHandler;
 import org.openecomp.policy.api.NotificationScheme;
 import org.openecomp.policy.api.PDPNotification;
@@ -79,45 +69,37 @@
 import org.openecomp.policy.api.PolicyClass;
 import org.openecomp.policy.api.PolicyConfig;
 import org.openecomp.policy.api.PolicyConfigException;
-import org.openecomp.policy.api.PolicyConfigStatus;
 import org.openecomp.policy.api.PolicyConfigType;
-import org.openecomp.policy.api.PolicyDecision;
 import org.openecomp.policy.api.PolicyDecisionException;
 import org.openecomp.policy.api.PolicyEngineException;
 import org.openecomp.policy.api.PolicyEventException;
+import org.openecomp.policy.api.PolicyException;
 import org.openecomp.policy.api.PolicyParameters;
 import org.openecomp.policy.api.PolicyResponse;
-import org.openecomp.policy.api.PolicyResponseStatus;
 import org.openecomp.policy.api.PolicyType;
 import org.openecomp.policy.api.PushPolicyParameters;
-import org.openecomp.policy.api.RuleProvider;
-//import org.openecomp.policy.utils.AAFPolicyClient;
-//import org.openecomp.policy.utils.AAFPolicyException;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
 import org.openecomp.policy.common.logging.flexlogger.Logger;
-
-import com.att.research.xacml.api.Advice;
-import com.att.research.xacml.api.AttributeAssignment;
-import com.att.research.xacml.api.Decision;
-import com.att.research.xacml.api.Obligation;
-import com.att.research.xacml.api.Request;
-import com.att.research.xacml.api.Response;
-import com.att.research.xacml.api.Result;
+import org.openecomp.policy.models.APIDictionaryResponse;
+import org.openecomp.policy.models.APIPolicyConfigResponse;
+import org.openecomp.policy.utils.AAFPolicyClient.Environment;
+import org.openecomp.policy.utils.PolicyUtils;
 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
-import org.openecomp.policy.xacml.std.pap.StdPAPPolicy;
-import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.xml.sax.InputSource;
 
-import com.att.research.xacml.api.pap.PAPException;
-import com.att.research.xacml.api.pap.PDPPolicy;
-import com.att.research.xacml.std.json.JSONRequest;
-import com.att.research.xacml.std.json.JSONResponse;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.base.CharMatcher;
-
-
+import com.att.aft.dme2.internal.gson.Gson;
+import com.att.aft.dme2.internal.gson.GsonBuilder;
+import com.fasterxml.jackson.core.JsonProcessingException;
 
 /**
  * PolicyEngine Implementation class
@@ -125,61 +107,54 @@
  * @version 1.0
  */
 public class StdPolicyEngine {
-	// Change the default Priority value here. 
-	private static final int defaultPriority = 9999;
+	private static final String ERROR_AUTH_GET_PERM = "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to: ";
+	private static final String DEFAULT_NOTIFICATION = "websocket";
 	
 	private String propertyFilePath = null;
+	private String clientEncoding = null;
+	private String contentType = null;
 	private static List<String> pdps = null;
-	private static List<String> paps = null;
 	private static String environment= null; 
 	private static String userName = null;
 	private static String pass = null; 
 	private static List<String> encoding = null;
-	private static List<String> encodingPAP = null;
-	private List<String> pdp_default = null;
-	private List<String> pap_default = null;
-	private List<String> type_default = null;
+	private static boolean junit = false;
+	private List<String> pdpDefault = null;
+	private List<String> typeDefault = null;
 	private List<String> notificationType = new ArrayList<String>();
-	private List<String> uebURLList = new ArrayList<String>();
+	private List<String> notificationURLList = new ArrayList<String>();
 	private NotificationScheme scheme = null;
 	private NotificationHandler handler = null;
-	private Matches match = null;
-	private Boolean decide = false;
-	private AutoClientUEB UEBClientThread = null;
+	private AutoClientUEB uebClientThread = null;
 	private Thread registerUEBThread = null;
-	private boolean UEBThread = false;
-	private String policyId = null;	
-	private String description = null;	
-	private String pushVersion = null;
-	private boolean isValid = false;
-	private int responseCode = 0;
-	private boolean unique = false;
-	private boolean junit = false;
-	//private AAFPolicyClient aafClient = null;
-	// Backward code. 
-	private String pyPDPClientFile = null;
-	
-	final private static String uniqueID = UUID.randomUUID ().toString ();
-	
-	private static Logger logger = FlexLogger.getLogger(StdPolicyConfig.class.getName());
+	private boolean uebThread = false;
+	private AutoClientDMAAP dmaapClientThread = null;
+	private Thread registerDMAAPThread = null;
+	private boolean dmaapThread = false;
+	private String topic = null;
+	private String apiKey = null;
+	private String apiSecret = null;
+
+	private static final String UNIQUEID = UUID.randomUUID ().toString ();
+	private static final Logger LOGGER = FlexLogger.getLogger(StdPolicyConfig.class.getName());
 	
 	/*
 	 * Taking the Property file even if it null.
 	 */
-	public StdPolicyEngine(String propertyFilePath)
-			throws PolicyEngineException {
-		setProperty(propertyFilePath);
+	public StdPolicyEngine(String propertyFilePath, String clientKey) throws PolicyEngineException {
+		setProperty(propertyFilePath, clientKey);
 	}
 
 	/*
 	 * Taking the Notification Constructor.
 	 */
-	public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme,
-			NotificationHandler handler) throws PolicyEngineException {
-		setProperty(propertyFilePath);
+	public StdPolicyEngine(String propertyFilePath,
+						   NotificationScheme scheme,
+						   NotificationHandler handler) throws PolicyEngineException {
+		setProperty(propertyFilePath, null);
 		this.scheme = scheme;
 		this.handler = handler;
-		if (!notificationType.get(0).equals("ueb")){
+		if ((!"ueb".equals(notificationType.get(0)))||(!"dmaap".equals(notificationType.get(0)))){
 			AutoClientEnd.setAuto(scheme, handler);
 		}
 		notification(scheme, handler);
@@ -188,1291 +163,590 @@
 	/*
 	 * Taking the Notification Constructor.
 	 */
-	public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme)
-			throws PolicyEngineException {
-		setProperty(propertyFilePath);
+	public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme) throws PolicyEngineException {
+		setProperty(propertyFilePath, null);
 		this.scheme = scheme;
 		setScheme(scheme);
 	}
 
-	// This Call will be used by PyPDP Requests
-	public StdPolicyEngine(List<String> configURL, List<String> configPapURL, List<String> encodingPAP, List<String> encoding, NotificationScheme scheme, NotificationHandler handler, String environment, String clientProperties, Boolean isTest) {
-		StdPolicyEngine.pdps = configURL;
-		StdPolicyEngine.paps = configPapURL;
-		StdPolicyEngine.encoding = encoding;
-		StdPolicyEngine.encodingPAP = encodingPAP;
-		StdPolicyEngine.environment = environment;
-		Properties props = new Properties();
-		props.setProperty("ENVIRONMENT", environment);
-		//Not Supported for 1610 Open Source
-		/*try {
-			aafClient = AAFPolicyClient.getInstance(props);
-		} catch (AAFPolicyException e) {
-			logger.error(XACMLErrorConstants.ERROR_UNKNOWN + e.getMessage());
-		}*/
-		pyPDPClientFile = clientProperties;
-		// Default Notification Type for PyPDPServers. 
-		notificationType.add("websocket");
-		if(!isTest){
-			notification(scheme, handler);
-		}
-	}
-
 	/*
 	 * sendEvent API Implementation
 	 */
-	public Collection<PolicyResponse> event(Map<String, String> eventAttributes, UUID requestID)
-			throws PolicyEventException {
-		Collection<PolicyResponse> policyResponse = null;
-		policyResponse = event(eventAttributes, requestID, userName, pass);
-		return policyResponse;
+	public Collection<PolicyResponse> sendEvent(Map<String, String> eventAttributes, UUID requestID) throws PolicyEventException {
+		return sendEventImpl(eventAttributes, requestID);
 	}
 	
 	/*
 	 * sendEvent API Implementation for eventRequestParameters 
 	 */
-	public Collection<PolicyResponse> event(EventRequestParameters eventRequestParameters) throws PolicyEventException{
-		Collection<PolicyResponse> response = event(eventRequestParameters.getEventAttributes(), eventRequestParameters.getRequestID());
-		return response;
+	public Collection<PolicyResponse> sendEvent(EventRequestParameters eventRequestParameters) throws PolicyEventException{
+		if(eventRequestParameters==null){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No event Request Parameters Given. ";
+			LOGGER.error(message);
+			throw new PolicyEventException(message);
+		}
+		return sendEventImpl(eventRequestParameters.getEventAttributes(), eventRequestParameters.getRequestID());
 	}
 
 	/*
-	 * getConfig API Implementation
-	 */
-	public Collection<PolicyConfig> config(String eCOMPComponentName,
-			String configName, Map<String, String> configAttributes, UUID requestID)
-			throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = null;
-		policyConfig = config(eCOMPComponentName, configName, configAttributes, requestID, userName, pass);
-		return policyConfig;
-	}
-
-	/*
-	 * getConfig API Implementation
-	 */
-	public Collection<PolicyConfig> config(String eCOMPComponentName,
-			String configName, UUID requestID) throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = null;
-		policyConfig = config(eCOMPComponentName, configName,null, requestID, userName, pass);
-		return policyConfig;
-	}
-
-	/*
-	 * getConfig API Implementation
-	 */
-	public Collection<PolicyConfig> config(String eCOMPComponentName, UUID requestID)
-			throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = null;
-		policyConfig = config(eCOMPComponentName, requestID, userName, pass);
-		return policyConfig;
-	}
-
-	/*
-	 * getConfig using the PolicyFileName Implementation
-	 */
-	public Collection<PolicyConfig> policyName(String policyName, UUID requestID)
-			throws PolicyConfigException {
-		Collection<PolicyConfig> policyConfig = null;
-		policyConfig = configPolicyName(policyName, requestID, userName, pass);
-		return policyConfig;
-	}
-	
-	/*
 	 * getConfig using configRequestParameters Implementation 
 	 */
-	public Collection<PolicyConfig> config(ConfigRequestParameters configRequestParameters) throws PolicyConfigException{
-		Collection<PolicyConfig> response = null;
-		response = configRequest(configRequestParameters, userName, pass);
-		return response;
+	public Collection<PolicyConfig> getConfig(ConfigRequestParameters configRequestParameters) throws PolicyConfigException{
+		return getConfigImpl(configRequestParameters);
 	}
 	
 	/*
 	 * listPolicies using configRequestParameters Implementation
 	 */
 	public Collection<String> listConfig(ConfigRequestParameters listPolicyRequestParameters) throws PolicyConfigException{
-		Collection<String> policyList = new ArrayList<String>();
-		policyList = listConfigRequest(listPolicyRequestParameters, userName, pass);
-		return policyList;
+		return listConfigImpl(listPolicyRequestParameters);
 	}
 
 	/*
 	 * getDecision using the decision Attributes.
 	 */
-	public DecisionResponse decide(String eCOMPComponentName,
-			Map<String, String> decisionAttributes, UUID requestID)
-			throws PolicyDecisionException {
-		DecisionResponse policyDecision = policyDecide(eCOMPComponentName,
-				decisionAttributes, requestID, userName, pass);
-		return policyDecision;
+	public DecisionResponse getDecision(String eCOMPComponentName, Map<String, String> decisionAttributes, UUID requestID) throws PolicyDecisionException {
+		return getDecisionImpl(eCOMPComponentName, decisionAttributes, requestID);
 	}
 	
 	/*
 	 * getDecision Using decisionRequestParameters.  
 	 */
-	public DecisionResponse decide(DecisionRequestParameters decisionRequestParameters) throws PolicyDecisionException{
-		DecisionResponse decision = decide(decisionRequestParameters.getECOMPComponentName(), decisionRequestParameters.getDecisionAttributes(), decisionRequestParameters.getRequestID());
-		return decision;
+	public DecisionResponse getDecision(DecisionRequestParameters decisionRequestParameters) throws PolicyDecisionException{
+		if(decisionRequestParameters==null){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Request Parameters Given. ";
+			LOGGER.error(message);
+			throw new PolicyDecisionException(message);
+		}
+		return getDecisionImpl(decisionRequestParameters.getECOMPComponentName(), decisionRequestParameters.getDecisionAttributes(), decisionRequestParameters.getRequestID());
+	}
+	
+	/*
+	 * getMetrics using metricsRequestParameters
+	 */
+	public MetricsResponse getMetrics(MetricsRequestParameters parameters) throws PolicyException{
+		return getMetricsImpl(parameters);
+	}
+	
+	public MetricsResponse getMetricsImpl(MetricsRequestParameters parameters) throws PolicyException{
+		StdMetricsResponse response = new StdMetricsResponse();
+		String resource = "getMetrics";
+		String body = new String();
+		
+		//  Create the Request
+		try {
+			if (parameters!=null) {
+				body = PolicyUtils.objectToJsonString(parameters);
+			}
+		} catch (JsonProcessingException e) {
+			String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
+			LOGGER.error(message);
+			throw new PolicyException(message, e);
+		}
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.GET, body, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+    	    if(exception.getCause()!=null && exception.getCause() instanceof HttpClientErrorException){
+                LOGGER.error(exception);
+                HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
+                response.setResponseCode(ex.getRawStatusCode());
+                response.setResponseMessage(exception.getMessage());
+                return response;
+            }else{
+                String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR+ "Error while processing results. please check logs.";
+                LOGGER.error(message, exception);
+                throw new PolicyException(message, exception);
+            }         
+        }
+		return response;
 	}
 	
 	/*
 	 * PushPolicy using pushPolicyParameters. 
 	 */
-	public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws Exception{
-		return pushPolicy(pushPolicyParameters, userName, pass);
+	public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws PolicyException{
+		return pushPolicyImpl(pushPolicyParameters);
 	}
 	
-	public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters, String userID, String passcode) throws Exception{
+	public PolicyChangeResponse pushPolicyImpl(PushPolicyParameters pushPolicyParameters) throws PolicyException{
 		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
 		String resource= "pushPolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseMessage(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseCode(401);
-			return response;
-		}
-		String plainName = null;
-		String scope = null;
-		try{
-			if(pushPolicyParameters.getPolicyName()!=null){
-				plainName = pushPolicyParameters.getPolicyName().substring(pushPolicyParameters.getPolicyName().lastIndexOf(".")+1, pushPolicyParameters.getPolicyName().length());
-				scope = pushPolicyParameters.getPolicyName().substring(0, pushPolicyParameters.getPolicyName().lastIndexOf("."));
-				logger.info("Name is "+ plainName +"   scope is "+ scope);
-			}
-		}catch(Exception e){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-		}
-
-		// check incoming requestID, if null then generate one here so the same id can be used for the multiple transactions for the same Push Policy request  (i.e. POST, PUT)
-		UUID requestID = pushPolicyParameters.getRequestID();
-		if (requestID == null) {
-			requestID = UUID.randomUUID();
-			logger.info("Request ID was not provided from input, so sending generated ID: " + requestID.toString());
-		} else {	
-			logger.info("Request ID was provided from input: " + requestID.toString());
-		}
-		// now use the local requestID field derived above to pass to the rest of the Push Policy process (below)
-		// response.setResponseMessage(pushPolicy(scope, plainName, pushPolicyParameters.getPolicyType(), pushPolicyParameters.getPdpGroup(), pushPolicyParameters.getRequestID()));
-		response.setResponseMessage(pushPolicy(scope, plainName, pushPolicyParameters.getPolicyType(), pushPolicyParameters.getPdpGroup(), requestID));
-		response.setResponseCode(responseCode);
-		return response;
+        String body = new String();
+        // Create Request. 
+        try {
+            body = PolicyUtils.objectToJsonString(pushPolicyParameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+            return processException(exception);
+        }
+        return response;
 	}
 	
 	/*
 	 * Delete a Policy using deletePolicyParameters
 	 */
-	public PolicyChangeResponse deletePolicy(DeletePolicyParameters parameters) throws Exception {
-		return deletePolicy(parameters, userName, pass);
+	public PolicyChangeResponse deletePolicy(DeletePolicyParameters parameters) throws PolicyException {
+		return deletePolicyImpl(parameters);
 	}
 	
-	public PolicyChangeResponse deletePolicy(DeletePolicyParameters parameters, String userID,String passcode) throws Exception {
+	public PolicyChangeResponse deletePolicyImpl(DeletePolicyParameters parameters) throws PolicyException {
 		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
 		String resource= "deletePolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseMessage(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseCode(401);
-			return response;
-		}
-		if (parameters.getPolicyComponent()!=null) {
-			if (parameters.getPolicyComponent().equalsIgnoreCase("PAP")) {
-				response.setResponseMessage(deletePolicyFromPAP(parameters));
-			} else if (parameters.getPolicyComponent().equalsIgnoreCase("PDP")) {
-				response.setResponseMessage(deletePolicyFromPDP(parameters));
-			} else {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy Component does not exist.");
-				response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy Component does not exist. Please enter either PAP or PDP to delete the policy from a specified Policy Component.");
-			}
-		} else {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Component given.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Component given.");
-		}
+		String body = new String();
+        // Create Request. 
+        try {
+            body = PolicyUtils.objectToJsonString(parameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.DELETE, body, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+            return processException(exception);
+        }
+        return response;
+	}
 
-		response.setResponseCode(responseCode);
-		return response;
+	/*
+	 * getDictionaryItem Using dictionaryParameters
+	 */
+	public DictionaryResponse getDictionaryItem(DictionaryParameters parameters) throws PolicyException {
+		return getDictionaryItemImpl(parameters);
+	}
+	
+	public DictionaryResponse getDictionaryItemImpl(DictionaryParameters parameters) throws PolicyException{
+		StdDictionaryResponse response = new StdDictionaryResponse();
+		String resource="getDictionaryItems";
+		String body = "{}";
+		// Create Request. 
+        try {
+            body = PolicyUtils.objectToJsonString(parameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<APIDictionaryResponse> result = callNewPDP(resource, HttpMethod.POST, body, APIDictionaryResponse.class);
+            // Process response
+            response = dictionaryResult(result.getBody());
+        } catch (Exception exception) {
+            if(exception.getCause().getMessage().contains("401")){
+                String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
+                LOGGER.error(message);
+                response.setResponseMessage(message);
+                response.setResponseCode(401);
+                return response;
+            }if(exception.getCause().getMessage().contains("400")){
+                String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
+                response.setResponseMessage(message);
+                response.setResponseCode(400);
+                return response;
+            }
+            String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from  PDP(s) " + pdps;
+            LOGGER.error(message, exception);
+            response.setResponseMessage(message);
+            response.setResponseCode(500);
+            return response;
+        }
+        return response;		
+	}
+	
+	@SuppressWarnings("unchecked")
+    private StdDictionaryResponse dictionaryResult(APIDictionaryResponse body) {
+        StdDictionaryResponse response = new StdDictionaryResponse();
+        response.setResponseCode(body.getResponseCode());
+        response.setResponseMessage(body.getResponseMessage());
+        response.setDictionaryData((Map<String, String>) body.getDictionaryData());
+        if(body.getDictionaryJson()!=null){
+            Gson objGson = new GsonBuilder().create();
+            String mapToJson = objGson.toJson(body.getDictionaryJson());
+            JsonReader jsonReader = Json.createReader(new StringReader(mapToJson));
+            JsonObject object = jsonReader.readObject();
+            jsonReader.close();
+            response.setDictionaryJson(object);
+        }
+        return response;
+    }
+
+    /*
+	 * createDictinaryItem Using dictionaryParameters. 
+	 */
+	public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws PolicyException{
+		return createUpdateDictionaryItemImpl(parameters, false);
 	}
 	
 	/*
-	 * createDictionaryItem using dictionaryParameters.
+	 * updateDictinaryItem Using dictionaryParameters. 
 	 */
-	public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws Exception{
+	public PolicyChangeResponse updateDictionaryItem(DictionaryParameters parameters) throws PolicyException{
+		return createUpdateDictionaryItemImpl(parameters, true);
+	}
+	
+	public PolicyChangeResponse createUpdateDictionaryItemImpl(DictionaryParameters parameters, boolean updateFlag) throws PolicyException{
 		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
-		
-		if(parameters.getDictionaryType()!=null || parameters.getDictionaryType().equals("")){
-			if(parameters.getDictionary()!=null || parameters.getDictionary().equals("")){
-				if(parameters.getDictionaryFields()!=null){
-					logger.info("Parameters are good... start create dictionary item API...");
-					
-					Map<String,String> dictionaryFields = parameters.getDictionaryFields().get(AttributeType.DICTIONARY);
-					
-					StdPAPPolicy newDictionaryItem = new StdPAPPolicy(parameters.getDictionaryType().toString(), parameters.getDictionary(), dictionaryFields);
-
-					String result = (String) callPAP(newDictionaryItem, new String[] {"operation=createDictionary", "apiflag=dictionaryApi"}, parameters.getRequestID(), "dictionaryItem");
-					
-					response.setResponseCode(responseCode);
-					response.setResponseMessage(result);
-
-				}else{
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary Fields given.");
-					response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary Fields given.");
-				}
-			}else{
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary given.");
-				response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary given.");
-			}
-		}else{
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary Type given.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary Type given.");
+		String resource = "createDictionaryItem";
+		if(updateFlag){
+		    resource = "updateDictionaryItem";
 		}
-		try{
-			
-		}catch(Exception e){
-
-		}
-		
-		return response;
+		String body = new String();
+        // Create Request. 
+        try {
+            body = PolicyUtils.objectToJsonString(parameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+            return processException(exception);
+        }
+        return response;
+	}
+	
+	/*
+	 * PolicyEngine Import  
+	 */
+	public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws PolicyException {
+		return policyEngineImportImpl(importParameters);
+	}
+	
+	public PolicyChangeResponse policyEngineImportImpl(ImportParameters importParameters) throws PolicyException {
+		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
+		String resource= "policyEngineImport";
+		LinkedMultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
+        // Create Request. 
+        try {
+            String body = PolicyUtils.objectToJsonString(importParameters);
+            parameters.set("importParametersJson", body);
+            parameters.set("file", new FileSystemResource(importParameters.getFilePath()));
+        } catch (Exception e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        contentType = MediaType.MULTIPART_FORM_DATA_VALUE;
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.POST, parameters, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+            return processException(exception);
+        } finally{
+            contentType = null;
+        }
+        return response;
 	}
 	
 	/*
 	 * createPolicy Using policyParameters. 
 	 */
-	public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws Exception{
-		return createPolicy(policyParameters, userName, pass);
-	}
-	
-	public PolicyChangeResponse createPolicy(PolicyParameters policyParameters, String userID, String passcode) throws Exception{
-		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
-		String resource= "createPolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseMessage(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseCode(401);
-			return response;
-		}
-		String plainName = null;
-		String scope = null;
-		String date = "NA";
-		if (policyParameters.getTtlDate()!=null){
-			date = ConvertDate(policyParameters.getTtlDate());
-		}
-		try{
-			if(policyParameters.getPolicyName()!=null){
-				plainName = policyParameters.getPolicyName().substring(policyParameters.getPolicyName().lastIndexOf(".")+1, policyParameters.getPolicyName().length());
-				scope = policyParameters.getPolicyName().substring(0, policyParameters.getPolicyName().lastIndexOf("."));
-				logger.info("Name is "+ plainName +"   scope is "+ scope);
-			}
-		}catch(Exception e){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-		}
-		if(policyParameters.getPolicyConfigType()!=null){
-			// This is Config Class Policy. 
-			// Firewall
-			if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.Firewall)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						json = stringToJsonObject(policyParameters.getConfigBody());
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						throw new Exception(message);
-					}
-					response.setResponseMessage(createConfigFirewallPolicy(plainName, json, scope, policyParameters.getRequestID(), userID, passcode,
-							policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body given.";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			//Base
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.Base)){
-				if(policyParameters.getConfigBody()!=null) {
-					if(policyParameters.getConfigBodyType()!=null){
-						response.setResponseMessage(createConfigPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getConfigName(),
-								policyParameters.getAttributes().get(AttributeType.MATCHING), policyParameters.getConfigBodyType().toString(), policyParameters.getConfigBody(), scope, policyParameters.getRequestID(), userID, passcode,
-								policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-					} else {
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body Type given.";
-						logger.error(message);
-						response.setResponseMessage(message);
-					}
-				} else {
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body given.";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			//BRMS Raw
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.BRMS_RAW)){
-				if(policyParameters.getConfigBody()!=null){
-					
-					/*public String createUpdateBRMSRawPolicy(String policyName, String policyDescription, Map<String,String> dyanamicFieldConfigAttributes,
-					 * String brmsRawBody, String policyScope, Boolean isEdit, UUID requestID)*/
-					response.setResponseMessage(createUpdateBRMSRawPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							policyParameters.getConfigBody(),scope, false, 
-							policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), 
-							date));
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					throw new Exception(message);
-				}
-			}
-			//BRMS Param
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.BRMS_PARAM)){
-				if(policyParameters.getConfigBody()!=null){
-			
-					response.setResponseMessage(createUpdateBRMSParamPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							policyParameters.getConfigBody(),scope, false, 
-							policyParameters.getRequestID(),policyParameters.getAttributes(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-							String.valueOf(policyParameters.getGuard()), date));
-				}else{
-					response.setResponseMessage(createUpdateBRMSParamPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							null,scope, false, 
-							policyParameters.getRequestID(),policyParameters.getAttributes(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-							String.valueOf(policyParameters.getGuard()), date));
-				}
-			}
-			// Micro Services Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.MicroService)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						json = stringToJsonObject(policyParameters.getConfigBody());
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						throw new Exception(message);
-					}
-					//call Micro Services Create API here
-					response.setResponseMessage(createUpdateMicroServicesPolicy(plainName, json, policyParameters.getEcompName(),
-													scope, false, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-													String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Micro Service or Attributes Config Body Present";
-					logger.error(message);
-					throw new Exception(message);
-				}
-			}
-			// ClosedLoop_Fault Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.ClosedLoop_Fault)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						if(validateNONASCIICharactersAndAllowSpaces(policyParameters.getConfigBody())){
-							json = stringToJsonObject(policyParameters.getConfigBody());
-						} else {
-							String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "The ClosedLoop JSON Contains Non ASCII Characters.";
-							logger.error(message);
-							response.setResponseCode(400);
-							response.setResponseMessage(message);
-							return response;
-						}
-						
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						response.setResponseCode(400);
-						response.setResponseMessage(message);
-						return response;
-						
-					}
-					//call ClosedLoop_Fault Create API here
-					response.setResponseMessage(createUpdateClosedLoopPolicy(plainName, json, policyParameters.getPolicyDescription(),
-													scope, false, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-													String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					response.setResponseMessage(message);
-					response.setResponseCode(400);
-					return response;
-				}
-			}
-			// ClosedLoop_PM Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.ClosedLoop_PM)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						if(validateNONASCIICharactersAndAllowSpaces(policyParameters.getConfigBody())){
-							json = stringToJsonObject(policyParameters.getConfigBody());
-						} else {
-							String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "The ClosedLoop PM JSON Contains Non ASCII Characters.";
-							logger.error(message);
-							response.setResponseMessage(message);
-							response.setResponseCode(400);
-							return response;
-							
-						}
-						
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						response.setResponseMessage(message);
-						response.setResponseCode(400);
-						return response;
-						
-					}
-					//call ClosedLoop_Fault Create API here
-					response.setResponseMessage(createUpdateClosedLoopPmPolicy(plainName, json, policyParameters.getPolicyDescription(),
-													scope, false, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-													String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					response.setResponseMessage(message);
-					response.setResponseCode(400);
-					return response;
-					
-				}
-			}
-			
-		} else if (policyParameters.getPolicyClass()!=null){ 
-			if(policyParameters.getPolicyClass().equals(PolicyClass.Action)){
-				// call Action Create API here. 
-				response.setResponseMessage(createUpdateActionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getAttributes().get(AttributeType.MATCHING), 
-						policyParameters.getDynamicRuleAlgorithmLabels(), policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-						policyParameters.getActionPerformer(), policyParameters.getActionAttribute(), scope, false, policyParameters.getRequestID()));
-			}else if(policyParameters.getPolicyClass().equals(PolicyClass.Decision)){
-				// Call Decision Create API here. 
-				if (policyParameters.getAttributes()!=null && policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)) {
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							policyParameters.getAttributes().get(AttributeType.MATCHING), policyParameters.getAttributes().get(AttributeType.SETTINGS), policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, false, policyParameters.getRequestID()));
-				}else if(policyParameters.getAttributes()!=null && !policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)){
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							null, policyParameters.getAttributes().get(AttributeType.SETTINGS), policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, false, policyParameters.getRequestID()));
-				}else if(policyParameters.getAttributes()!=null && policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && !policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)){
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							policyParameters.getAttributes().get(AttributeType.MATCHING), null, policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, false, policyParameters.getRequestID()));
-				}else{
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							null, null, policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, false, policyParameters.getRequestID()));
-				}
-			}
-		} else {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Class found.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Class found.");
-		}
-		response.setResponseCode(responseCode);
-		return response;
+	public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws PolicyException{
+		return createUpdatePolicyImpl(policyParameters, false);
 	}
 	
 	/*
 	 * updatePolicy using policyParameters. 
 	 */
-	public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws Exception{
-		return updatePolicy(policyParameters, userName, pass);
+	public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws PolicyException{
+		return createUpdatePolicyImpl(policyParameters, true);
 	}
 	
-	public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters,String userID, String passcode) throws Exception{
+	public PolicyChangeResponse createUpdatePolicyImpl(PolicyParameters policyParameters, boolean updateFlag) throws PolicyException{
 		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
-		String resource= "updatePolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseMessage(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseCode(401);
-			return response;
+		String resource= "createPolicy";
+		if(updateFlag){
+		    resource="updatePolicy";
 		}
-		String plainName = null;
-		String scope = null;
-		String date = "NA";
-		if (policyParameters.getTtlDate()!=null){
-			date = ConvertDate(policyParameters.getTtlDate());
-		}
-		try{
-			if(policyParameters.getPolicyName()!=null){
-				plainName = policyParameters.getPolicyName().substring(policyParameters.getPolicyName().lastIndexOf(".")+1, policyParameters.getPolicyName().length());
-				scope = policyParameters.getPolicyName().substring(0, policyParameters.getPolicyName().lastIndexOf("."));
-				logger.info("Name is "+ plainName +"   scope is "+ scope);
-			}
-		}catch(Exception e){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-		}
-		if(policyParameters.getPolicyConfigType()!=null){
-			// This is Config Class Policy.
-			//Firewall
-			if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.Firewall)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						json = stringToJsonObject(policyParameters.getConfigBody());
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						throw new Exception(message);
-					}
-					response.setResponseMessage(updateConfigFirewallPolicy(plainName, json, scope, policyParameters.getRequestID(), userID, passcode,policyParameters.getRiskLevel(), 
-							policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body given.";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			//Base Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.Base)){
-				if(policyParameters.getConfigBody()!=null) {
-					if(policyParameters.getConfigBodyType()!=null){
-						response.setResponseMessage(updateConfigPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getConfigName(),
-								policyParameters.getAttributes().get(AttributeType.MATCHING), policyParameters.getConfigBodyType().toString(), policyParameters.getConfigBody(), scope, 
-								policyParameters.getRequestID(), userID, passcode, policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-					} else {
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body Type given.";
-						logger.error(message);
-						response.setResponseMessage(message);
-					}
-				} else {
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Config Body given.";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			//BRMS Raw
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.BRMS_RAW)){
-				if(policyParameters.getConfigBody()!=null){
-					/*public String createUpdateBRMSRawPolicy(String policyName, String policyDescription, Map<String,String> dyanamicFieldConfigAttributes,
-					 * String brmsRawBody, String policyScope, Boolean isEdit, UUID requestID)*/
-					response.setResponseMessage(createUpdateBRMSRawPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							policyParameters.getConfigBody(),scope, true, 
-							policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					throw new Exception(message);
-				}
-			}
-			//BRMS Param
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.BRMS_PARAM)){
-				if(policyParameters.getConfigBody()!=null){
-					
-				/*	public String createUpdateBRMSParamPolicy(String policyName, String policyDescription, Map<AttributeType, Map<String, String>>  dyanamicFieldConfigAttributes,
-							String brmsRawBody, String policyScope, Boolean isEdit, 
-							UUID requestID,Map<String,String> drlRuleAndUIParams)*/
-					response.setResponseMessage(createUpdateBRMSParamPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							policyParameters.getConfigBody(),scope, true, 
-							policyParameters.getRequestID(),policyParameters.getAttributes(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-				}else{
-					response.setResponseMessage(createUpdateBRMSParamPolicy(plainName, policyParameters.getPolicyDescription(),policyParameters.getAttributes(),
-							null,scope, true, 
-							policyParameters.getRequestID(),policyParameters.getAttributes(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-				}
-			}
-			// Micro Services Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.MicroService)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						json = stringToJsonObject(policyParameters.getConfigBody());
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						throw new Exception(message);
-					}
-					//call Micro Services Create API here
-					response.setResponseMessage(createUpdateMicroServicesPolicy(plainName, json, policyParameters.getEcompName(),
-							scope, true, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Micro Service or Attributes Config Body Present";
-					logger.error(message);
-					throw new Exception(message);
-				}
-			}
-			// ClosedLoop_Fault Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.ClosedLoop_Fault)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						if(validateNONASCIICharactersAndAllowSpaces(policyParameters.getConfigBody())){
-							json = stringToJsonObject(policyParameters.getConfigBody());
-						} else {
-							String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "The ClosedLoop JSON Contains Non ASCII Characters.";
-							logger.error(message);
-							response.setResponseMessage(message);
-							return response;
-						}
-						
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						response.setResponseMessage(message);
-						return response;
-					}
-					//call ClosedLoop_Fault Create API here
-					response.setResponseMessage(createUpdateClosedLoopPolicy(plainName, json, policyParameters.getPolicyDescription(),
-													scope, true, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			// ClosedLoop_PM Policy
-			else if(policyParameters.getPolicyConfigType().equals(PolicyConfigType.ClosedLoop_PM)){
-				if(policyParameters.getConfigBody()!=null){
-					JsonObject json = null;
-					try{
-						if(validateNONASCIICharactersAndAllowSpaces(policyParameters.getConfigBody())){
-							json = stringToJsonObject(policyParameters.getConfigBody());
-						} else {
-							String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ "The ClosedLoop PM JSON Contains Non ASCII Characters.";
-							logger.error(message);
-							response.setResponseMessage(message);
-							return response;
-						}
-						
-					}catch(Exception e){
-						String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
-						logger.error(message);
-						response.setResponseMessage(message);
-						return response;
-					}
-					//call ClosedLoop_Fault Create API here
-					response.setResponseMessage(createUpdateClosedLoopPmPolicy(plainName, json, policyParameters.getPolicyDescription(),
-													scope, true, policyParameters.getRequestID(),policyParameters.getRiskLevel(), policyParameters.getRiskType(), 
-													String.valueOf(policyParameters.getGuard()), date));
-					
-				}else{
-					String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " No Config Body Present";
-					logger.error(message);
-					response.setResponseMessage(message);
-				}
-			}
-			
-		}else{
-			
-			if(policyParameters.getPolicyClass().equals(PolicyClass.Action)){
-				// call Action Update API here. 
-				response.setResponseMessage(createUpdateActionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getAttributes().get(AttributeType.MATCHING), 
-						policyParameters.getDynamicRuleAlgorithmLabels(), policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-						policyParameters.getActionPerformer(), policyParameters.getActionAttribute(), scope, true, policyParameters.getRequestID()));
-			
-			}else if(policyParameters.getPolicyClass().equals(PolicyClass.Decision)){
-				// Call Decision Create API here. 
-				if (policyParameters.getAttributes()!=null && policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)) {
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							policyParameters.getAttributes().get(AttributeType.MATCHING), policyParameters.getAttributes().get(AttributeType.SETTINGS), policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, true, policyParameters.getRequestID()));
-				}else if(policyParameters.getAttributes()!=null && !policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)){
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							null, policyParameters.getAttributes().get(AttributeType.SETTINGS), policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, true, policyParameters.getRequestID()));
-				}else if(policyParameters.getAttributes()!=null && policyParameters.getAttributes().containsKey(AttributeType.MATCHING) && !policyParameters.getAttributes().containsKey(AttributeType.SETTINGS)){
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							policyParameters.getAttributes().get(AttributeType.MATCHING), null, policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, true, policyParameters.getRequestID()));
-				}else{
-					response.setResponseMessage(createUpdateDecisionPolicy(plainName, policyParameters.getPolicyDescription(), policyParameters.getEcompName(), policyParameters.getRuleProvider(),
-							null, null, policyParameters.getDynamicRuleAlgorithmLabels(), 
-							policyParameters.getDynamicRuleAlgorithmField1(), policyParameters.getDynamicRuleAlgorithmFunctions(), policyParameters.getDynamicRuleAlgorithmField2(), 
-							scope, true, policyParameters.getRequestID()));
-				}
-			}
-		}
-		response.setResponseCode(responseCode);
+		String body = new String();
+        // Create Request. 
+        try {
+            body = PolicyUtils.objectToJsonString(policyParameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
+            // Process response
+            response.setResponseMessage(result.getBody());
+            response.setResponseCode(result.getStatusCode().value());
+        } catch (PolicyException exception) {
+            return processException(exception);
+        }
+        return response;
+	}
+	
+	private PolicyChangeResponse processException(PolicyException exception) throws PolicyException {
+	    StdPolicyChangeResponse response = new StdPolicyChangeResponse();
+	    if(exception.getCause()!=null && exception.getCause() instanceof HttpClientErrorException){
+            LOGGER.error(exception);
+            HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
+            response.setResponseCode(ex.getRawStatusCode());
+            response.setResponseMessage(exception.getMessage());
+            return response;
+        }else{
+            String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR+ "Error while processing results. please check logs.";
+            LOGGER.error(message, exception);
+            throw new PolicyException(message, exception);
+        }
+    }
+
+    public DecisionResponse getDecisionImpl(String eCOMPComponentName,
+											Map<String, String> decisionAttributes,
+											UUID requestID) throws PolicyDecisionException {
+		String resource= "getDecision";
+		StdDecisionResponse response = new StdDecisionResponse();
+        String body = new String();
+        // Create Request. 
+        try {
+            DecisionRequestParameters decisionRequestParameters = new DecisionRequestParameters();
+            decisionRequestParameters.setDecisionAttributes(decisionAttributes);
+            decisionRequestParameters.setECOMPComponentName(eCOMPComponentName);
+            decisionRequestParameters.setRequestID(requestID);
+            body = PolicyUtils.objectToJsonString(decisionRequestParameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyDecisionException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<StdDecisionResponse> result = callNewPDP(resource, HttpMethod.POST, body, StdDecisionResponse.class);
+            // Process response
+            response = result.getBody();
+        } catch (Exception exception) {
+            if(exception.getCause().getMessage().contains("401")){
+                String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
+                LOGGER.error(message);
+                throw new PolicyDecisionException(message, exception);
+            }if(exception.getCause().getMessage().contains("400")){
+                String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
+                LOGGER.error(message);
+                throw new PolicyDecisionException(message, exception);
+            }
+            String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from  PDP(s) " + pdps;
+            LOGGER.error(message, exception);
+            throw new PolicyDecisionException(message, exception);
+        }
+        return response;
+	}
+	
+    public Collection<PolicyConfig> getConfigImpl(ConfigRequestParameters configRequestParameters) throws PolicyConfigException{
+	    String resource= "getConfig";
+		ArrayList<PolicyConfig> response = new ArrayList<PolicyConfig>();
+		String body = new String();
+		// Create Request. 
+		try {
+            body = PolicyUtils.objectToJsonString(configRequestParameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyConfigException(message, e);
+        }
+		// Get Response. 
+		try {
+            ResponseEntity<APIPolicyConfigResponse[]> result = callNewPDP(resource, HttpMethod.POST, body, APIPolicyConfigResponse[].class);
+            // Process Response
+            response = configResult(result.getBody());
+        } catch (Exception exception) {
+            if(exception.getCause().getMessage().contains("401")){
+                String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
+                LOGGER.error(message);
+                throw new PolicyConfigException(message, exception);
+            }if(exception.getCause().getMessage().contains("400")){
+                String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
+                LOGGER.error(message);
+                throw new PolicyConfigException(message, exception);
+            }
+            String message = XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Unable to get valid Response from  PDP(s) " + pdps;
+            LOGGER.error(message, exception);
+            throw new PolicyConfigException(message, exception);
+        }
 		return response;
 	}
-	
-	public DecisionResponse policyDecide(String eCOMPComponentName,
-			Map<String, String> decisionAttributes, UUID requestID, String userID, String passcode)
-			throws PolicyDecisionException {
-		String resource= "getDecision";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyDecisionException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		DecisionResponse policyDecision;
-		if (eCOMPComponentName == null || eCOMPComponentName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given : " + eCOMPComponentName);
-			throw new PolicyDecisionException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given.");
-		}
-		if (decisionAttributes != null && !decisionAttributes.isEmpty()) {
-			JsonArrayBuilder resourceArray = Json.createArrayBuilder();
-			for (String key : decisionAttributes.keySet()) {
-				if (key.isEmpty()) {
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an Empty Key");
-					throw new PolicyDecisionException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an empty Key");
-				}
-				JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
-				if (decisionAttributes.get(key).matches("[0-9]+")) {
-					int val = Integer.parseInt(decisionAttributes.get(key));
-					resourceBuilder.add("Value", val);
-				} else {
-					resourceBuilder.add("Value", decisionAttributes.get(key));
-				}
-				resourceBuilder.add("AttributeId", key);
-				resourceArray.add(resourceBuilder);
-			}
-			JsonObject model = Json
-					.createObjectBuilder()
-					.add("Request",
-							Json.createObjectBuilder()
-									.add("AccessSubject",
-											Json.createObjectBuilder()
-													.add("Attribute",
-															Json.createObjectBuilder()
-																	.add("Value",
-																			eCOMPComponentName)
-																	.add("AttributeId",
-																			"ECOMPName")))
-									.add("Resource",
-											Json.createObjectBuilder().add(
-													"Attribute", resourceArray))
-									.add("Action",
-											Json.createObjectBuilder()
-													.add("Attribute",
-															Json.createObjectBuilder()
-																	.add("Value",
-																			"DECIDE")
-																	.add("AttributeId",
-																			"urn:oasis:names:tc:xacml:1.0:action:action-id"))))
-					.build();
-			try {
-				decide = true;
-				policyDecision = decisionResult(generateRequest(model
-						.toString(), requestID));
-			} catch (Exception e) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-				decide = false;
-				throw new PolicyDecisionException(e);
-			}
-		} else {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Attributes Given. ");
-			throw new PolicyDecisionException(XACMLErrorConstants.ERROR_DATA_ISSUE +"No DecisionAttributes Given.");
-		}
-		decide = false;
-		return policyDecision;
-	}
+    
+    private ArrayList<PolicyConfig> configResult(APIPolicyConfigResponse[] response) throws PolicyConfigException {
+        ArrayList<PolicyConfig> result = new ArrayList<PolicyConfig>();
+        if(response!=null && response.length>0){
+            for(APIPolicyConfigResponse policyConfigResponse: response){
+                StdPolicyConfig policyConfig = new StdPolicyConfig();
+                policyConfig.setConfigStatus(policyConfigResponse.getPolicyConfigMessage());
+                policyConfig.setMatchingConditions(policyConfigResponse.getMatchingConditions());
+                policyConfig.setPolicyConfigStatus(policyConfigResponse.getPolicyConfigStatus());
+                policyConfig.setPolicyName(policyConfigResponse.getPolicyName());
+                policyConfig.setPolicyType(policyConfigResponse.getType());
+                policyConfig.setPolicyVersion(policyConfigResponse.getPolicyVersion());
+                policyConfig.setResponseAttributes(policyConfigResponse.getResponseAttributes());
+                setMatches(policyConfig.getMatchingConditions());
+                if(policyConfigResponse.getType()!=null){
+                    try {
+                        switch (policyConfigResponse.getType()) {
+                            case JSON:
+                                JsonReader jsonReader = Json.createReader(new StringReader(policyConfigResponse.getConfig()));
+                                JsonObject object = jsonReader.readObject();
+                                jsonReader.close();
+                                policyConfig.setJsonObject(object);
+                                break;
+                            case OTHER:
+                                policyConfig.setOther(policyConfigResponse.getConfig());
+                                break;
+                            case PROPERTIES:
+                                Properties props = new Properties();
+                                props.putAll(policyConfigResponse.getProperty());
+                                policyConfig.setProperties(props);
+                                break;
+                            case XML:
+                                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                                DocumentBuilder builder;
+                                builder = factory.newDocumentBuilder();
+                                policyConfig.setDocument(builder.parse(new InputSource(new StringReader(policyConfigResponse.getConfig()))));
+                                break;
+                        }
+                    } catch (Exception e) {
+                        LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ e);
+                        throw new PolicyConfigException(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the config", e);
+                    }
+                }
+                result.add(policyConfig);
+            }
+        }
+        return result;
+    }
 
-	public Collection<PolicyConfig> configPolicyName(String policyName, UUID requestID, String userID, String passcode)
-			throws PolicyConfigException {
-		String resource= "getConfigByPolicyName";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
-		if (policyName == null || policyName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE+ "No Policy FileName specified!! : " + policyName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE+"No Policy FileName specified!!");
-		}
-		if(policyName!= null && !policyName.trim().equals("") && !policyName.endsWith("xml")){
-			policyName = policyName + ".[\\d].*";
-		}
-		JsonObject model = Json
-				.createObjectBuilder()
-				.add("Request",
-						Json.createObjectBuilder()
-								.add("AccessSubject",
-										Json.createObjectBuilder().add(
-												"Attribute",
-												Json.createObjectBuilder()
-														.add("Value",
-																policyName)
-														.add("AttributeId",
-																"PolicyName")))
-								.add("Action",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"ACCESS")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-								.add("Resource",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"Config")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:resource:resource-id"))))
-				.build();
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), requestID));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
-		return policyConfig;
-	}
+    private void setMatches(Map<String, String> matchingConditions) {
+        Matches match = new Matches();
+        HashMap<String, String> configAttributes = new HashMap<String,String>();
+        try{
+            for(String key: matchingConditions.keySet()){
+                if(key.equalsIgnoreCase("ECOMPName")){
+                    match.setEcompName(matchingConditions.get(key));
+                }else if(key.equalsIgnoreCase("ConfigName")){
+                    match.setConfigName(matchingConditions.get(key));
+                }else{
+                    configAttributes.put(key, matchingConditions.get(key));
+                }
+            }
+            if(!configAttributes.isEmpty()){
+                match.setConfigAttributes(configAttributes);
+            }
+            MatchStore.storeMatch(match);
+        }catch(Exception e){
+            LOGGER.info("StoreMatch failed for Ecomp:"
+                    + match.getEcompName() + " Config: "
+                    + match.getConfigName());
+        }
+    }
 
-	public Collection<PolicyConfig> config(String eCOMPComponentName, UUID requestID, String userID, String passcode)
-			throws PolicyConfigException {
-		String resource= "getConfig";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
-		if (eCOMPComponentName == null || eCOMPComponentName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given : " + eCOMPComponentName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given.");
-		}
-		JsonObject model = Json
-				.createObjectBuilder()
-				.add("Request",
-						Json.createObjectBuilder()
-								.add("AccessSubject",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		eCOMPComponentName)
-																.add("AttributeId",
-																		"ECOMPName")))
-								.add("Action",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"ACCESS")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-								.add("Resource",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"Config")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:resource:resource-id"))))
-				.build();
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), requestID));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
-		return policyConfig;
-	}
+    /*
+     * Generic Rest Client to call PDP services. 
+     */
+    private <T> ResponseEntity<T> callNewPDP(String resource,
+            HttpMethod method, Object body, Class<T> responseType) throws PolicyException{
+        RestTemplate restTemplate = new RestTemplate();
+        HttpEntity<?> requestEntity = new HttpEntity<>(body, getHeaders());
+        ResponseEntity<T> result = null;
+        HttpClientErrorException exception = null;
+        int pdpsCount = 0;
+        while(pdpsCount < pdps.size()){
+            try{
+                result = restTemplate.exchange(pdps.get(0)+"/api/" + resource, method, requestEntity, responseType);
+            }catch(HttpClientErrorException e){
+                LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
+                exception = e;
+            }catch(Exception e){
+                LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
+                exception = new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
+            }
+            finally{
+                if(result == null){
+                    Collections.rotate(pdps, -1);
+                    Collections.rotate(encoding, -1);
+                    pdpsCount++;
+                }else{
+                    break;
+                }
+            }
+        }
+        if(exception != null && exception.getStatusCode()!=null){
+            if(exception.getStatusCode().equals(HttpStatus.UNAUTHORIZED)){
+                String message = XACMLErrorConstants.ERROR_PERMISSIONS +":"+exception.getStatusCode()+":" +ERROR_AUTH_GET_PERM + resource;
+                LOGGER.error(message);
+                throw new PolicyException(message, exception);
+            }
+            if(exception.getStatusCode().equals(HttpStatus.BAD_REQUEST)){
+                String message = XACMLErrorConstants.ERROR_DATA_ISSUE + ":"+exception.getStatusCode()+":" + exception.getResponseBodyAsString();
+                LOGGER.error(message);
+                throw new PolicyException(message, exception);
+            }
+            if(exception.getStatusCode().equals(HttpStatus.NOT_FOUND)){
+                String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps + exception;
+                LOGGER.error(message);
+                throw new PolicyException(message, exception);
+            }
+            String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + ":"+exception.getStatusCode()+":" + exception.getResponseBodyAsString();
+            LOGGER.error(message);
+            throw new PolicyException(message, exception);
+        }
+        return result;
+    }
 
-	public Collection<PolicyConfig> config(String eCOMPComponentName,
-			String configName, UUID requestID, String userID, String passcode) throws PolicyConfigException {
-		String resource= "getConfig";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
-		if (eCOMPComponentName == null || eCOMPComponentName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given : " + eCOMPComponentName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given.");
-		}
-		if (configName == null || configName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No configName given : " + configName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +"No configName given.");
-		}
-		JsonObject model = Json
-				.createObjectBuilder()
-				.add("Request",
-						Json.createObjectBuilder()
-								.add("AccessSubject",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createArrayBuilder()
-																.add(Json
-																		.createObjectBuilder()
-																		.add("Value",
-																				eCOMPComponentName)
-																		.add("AttributeId",
-																				"ECOMPName"))
-																.add(Json
-																		.createObjectBuilder()
-																		.add("Value",
-																				configName)
-																		.add("AttributeId",
-																				"ConfigName"))))
-								.add("Action",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"ACCESS")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-								.add("Resource",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"Config")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:resource:resource-id"))))
-				.build();
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), requestID));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
+    private HttpHeaders getHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("ClientAuth", "Basic " + clientEncoding);
+        headers.set("Authorization", "Basic " + encoding.get(0));
+        if(contentType!=null){
+            headers.set("Content-Type", contentType.toString());
+        }else{
+            headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
+        }
+        headers.set("Environment", environment);
+        return headers;
+    }
 
-		return policyConfig;
-	}
+    private void setClientEncoding() {
+        Base64.Encoder encoder = Base64.getEncoder();
+        clientEncoding = encoder.encodeToString((userName+":"+pass).getBytes(StandardCharsets.UTF_8));
+    }
 
-	public Collection<PolicyConfig> config(String eCOMPComponentName,
-			String configName, Map<String, String> configAttributes, UUID requestID, String userID, String passcode)
-			throws PolicyConfigException {
-		String resource= "getConfig";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
-		if (eCOMPComponentName == null || eCOMPComponentName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given : " + eCOMPComponentName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName given.");
-		}
-		if (configName == null || configName.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No configName given : " + configName);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +"No configName given.");
-		}
-		if (configAttributes != null && !configAttributes.isEmpty()) {
-			if(!configAttributes.containsKey("RiskType")){
-				configAttributes.put("RiskType", ".*");
-			}
-			if(!configAttributes.containsKey("RiskLevel")){
-				configAttributes.put("RiskLevel", ".*");
-			}
-			if(!configAttributes.containsKey("guard")){
-				configAttributes.put("guard", ".*");
-			}
-			if(!configAttributes.containsKey("TTLDate")){
-				configAttributes.put("TTLDate", ".*");
-			}
-		}else{
-			// ConfigAttributes is Null. So add basic values. 
-			configAttributes = new HashMap<String,String>();
-			configAttributes.put("RiskType", ".*");
-			configAttributes.put("RiskLevel", ".*");
-			configAttributes.put("guard", ".*");
-			configAttributes.put("TTLDate", ".*");
-		}
-		JsonArrayBuilder resourceArray = Json.createArrayBuilder();
-		for (String key : configAttributes.keySet()) {
-			if (key.isEmpty()) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an empty Key");
-				throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +"Cannot have an empty Key");
-			}
-			JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
-			/*if (configAttributes.get(key).matches("[0-9]+")) {
-				int val = Integer.parseInt(configAttributes.get(key));
-				resourceBuilder.add("Value", val);
-			} else {*/
-			resourceBuilder.add("Value", configAttributes.get(key));
-			resourceBuilder.add("AttributeId", key);
-			resourceArray.add(resourceBuilder);
-		}
-		JsonObject model = Json
-			.createObjectBuilder()
-			.add("Request",
-					Json.createObjectBuilder()						
-							.add("AccessSubject",
-									Json.createObjectBuilder()
-												.add("Attribute",
-													Json.createArrayBuilder()
-															.add(Json
-																	.createObjectBuilder()
-																	.add("Value",
-																			eCOMPComponentName)
-																	.add("AttributeId",
-																			"ECOMPName"))
-															.add(Json
-																	.createObjectBuilder()
-																	.add("Value",
-																			configName)
-																	.add("AttributeId",
-																			"ConfigName"))))
-							.add("Action",
-									Json.createObjectBuilder()
-												.add("Attribute",
-													Json.createObjectBuilder()
-															.add("Value",
-																		"ACCESS")
-															.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-							.add("Resource",
-									Json.createObjectBuilder()
-												.add("Attribute",
-														resourceArray
-																.add(Json.createObjectBuilder()
-																		.add("Value",
-																				"Config")
-																		.add("AttributeId",
-																				"urn:oasis:names:tc:xacml:1.0:resource:resource-id")))))
-				.build();
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), requestID));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
-		return policyConfig;
-	}
-	
-	public Collection<PolicyConfig> configRequest(ConfigRequestParameters configRequestParameters, String userID, String passcode) throws PolicyConfigException{
-		String resource= "getConfig";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
-		unique = false;
-		if(configRequestParameters==null){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No config Request Parameters given ");
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No config Request Parameters given.");
-		}
-		if(configRequestParameters.getEcompName() == null && configRequestParameters.getPolicyName() == null){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot proceed without eCOMPComponentName or PolicyName");
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No eCOMPComponentName or PolicyName given.");
-		}
-		String policyName = configRequestParameters.getPolicyName();
-		if(policyName!= null && !policyName.trim().equals("") && !policyName.endsWith("xml")){
-			policyName = policyName + ".[\\d].*";
-		}
-		JsonArrayBuilder subjectArray = Json.createArrayBuilder();
-		JsonArrayBuilder resourceArray = Json.createArrayBuilder();
-		if(configRequestParameters.getPolicyName()!=null){
-			JsonObjectBuilder subjectBuilder = Json.createObjectBuilder();
-			subjectBuilder.add("Value", policyName);
-			subjectBuilder.add("AttributeId", "PolicyName");
-			subjectArray.add(subjectBuilder);
-		}else{
-			logger.info("PolicyName values are not given. ");
-		}
-		if(configRequestParameters.getEcompName()!=null){
-			JsonObjectBuilder subjectBuilder = Json.createObjectBuilder();
-			subjectBuilder.add("Value", configRequestParameters.getEcompName());
-			subjectBuilder.add("AttributeId", "ECOMPName");
-			subjectArray.add(subjectBuilder);
-			if(configRequestParameters.getConfigName()!=null){
-				subjectBuilder = Json.createObjectBuilder();
-				subjectBuilder.add("Value", configRequestParameters.getConfigName());
-				subjectBuilder.add("AttributeId", "ConfigName");
-				subjectArray.add(subjectBuilder);
-				Map<String,String> configAttributes = configRequestParameters.getConfigAttributes();
-				if (configAttributes != null && !configAttributes.isEmpty()) {
-					if(!configAttributes.containsKey("RiskType")){
-						configAttributes.put("RiskType", ".*");
-					}
-					if(!configAttributes.containsKey("RiskLevel")){
-						configAttributes.put("RiskLevel", ".*");
-					}
-					if(!configAttributes.containsKey("guard")){
-						configAttributes.put("guard", ".*");
-					}
-					if(!configAttributes.containsKey("TTLDate")){
-						configAttributes.put("TTLDate", ".*");
-					}
-				}else{
-					// ConfigAttributes is Null. So add basic values. 
-					configAttributes = new HashMap<String,String>();
-					configAttributes.put("RiskType", ".*");
-					configAttributes.put("RiskLevel", ".*");
-					configAttributes.put("guard", ".*");
-					configAttributes.put("TTLDate", ".*");
-				}
-				for (String key : configAttributes.keySet()) {
-					if (key.isEmpty()) {
-						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an empty Key");
-						throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +"Cannot have an empty Key");
-					}
-					JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
-					/*if (configAttributes.get(key).matches("[0-9]+")) {
-						int val = Integer.parseInt(configAttributes.get(key));
-						resourceBuilder.add("Value", val);
-					} else {*/
-					resourceBuilder.add("Value", configAttributes.get(key));
-					resourceBuilder.add("AttributeId", key);
-					resourceArray.add(resourceBuilder);
-				}
-			}else{
-				logger.info("Config Name is not given. ");
-			}
-		}else{
-			logger.info("Ecomp Name is not given. ");
-		}
-		JsonObject model = Json
-				.createObjectBuilder()
-				.add("Request",
-						Json.createObjectBuilder()
-								.add("AccessSubject",
-										Json.createObjectBuilder()
-												.add("Attribute",subjectArray))
-								.add("Action",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"ACCESS")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-								.add("Resource",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														resourceArray
-																.add(Json
-																		.createObjectBuilder()
-																		.add("Value",
-																				"Config")
-																		.add("AttributeId",
-																				"urn:oasis:names:tc:xacml:1.0:resource:resource-id")))))
-				.build();
-		logger.debug("Generated JSON Request is: " + model.toString());
-		if(configRequestParameters.getUnique()){
-			logger.info("Requested for Unique Result only. ");
-			unique = true;
-		}
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), configRequestParameters.getRequestID()));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
-		return policyConfig;
-	}
-	
-	public Collection<String> listConfigRequest(ConfigRequestParameters listRequestParameters, String userID, String passcode) throws PolicyConfigException{
-		String resource= "listConfig";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyConfig> policyConfig = null;
+    public Collection<String> listConfigImpl(ConfigRequestParameters listRequestParameters) throws PolicyConfigException{
 		Collection<String> policyList = new ArrayList<String>();
-		
-		unique = false;
-		if(listRequestParameters==null){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Request Parameters given ");
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Request Parameters given.");
-		}
-		
 		if (junit){
 			policyList.add("Policy Name: listConfigTest");
 			return policyList;
 		}
-
-		String policyName = listRequestParameters.getPolicyName();
-		if(policyName!= null && !policyName.trim().equals("") && !policyName.endsWith("xml")){
-			policyName = policyName + ".[\\d].*";
-		}
-		JsonArrayBuilder subjectArray = Json.createArrayBuilder();
-		JsonArrayBuilder resourceArray = Json.createArrayBuilder();
-		if(listRequestParameters.getPolicyName()!=null){
-			JsonObjectBuilder subjectBuilder = Json.createObjectBuilder();
-			subjectBuilder.add("Value", policyName);
-			subjectBuilder.add("AttributeId", "PolicyName");
-			subjectArray.add(subjectBuilder);
-		}else{
-			logger.info("PolicyName values are not given. ");
-		}
-		if(listRequestParameters.getEcompName()!=null){
-			JsonObjectBuilder subjectBuilder = Json.createObjectBuilder();
-			subjectBuilder.add("Value", listRequestParameters.getEcompName());
-			subjectBuilder.add("AttributeId", "ECOMPName");
-			subjectArray.add(subjectBuilder);
-			if(listRequestParameters.getConfigName()!=null){
-				subjectBuilder = Json.createObjectBuilder();
-				subjectBuilder.add("Value", listRequestParameters.getConfigName());
-				subjectBuilder.add("AttributeId", "ConfigName");
-				subjectArray.add(subjectBuilder);
-				Map<String,String> configAttributes = listRequestParameters.getConfigAttributes();
-				if (configAttributes != null && !configAttributes.isEmpty()) {
-					if(!configAttributes.containsKey("RiskType")){
-						configAttributes.put("RiskType", ".*");
-					}
-					if(!configAttributes.containsKey("RiskLevel")){
-						configAttributes.put("RiskLevel", ".*");
-					}
-					if(!configAttributes.containsKey("guard")){
-						configAttributes.put("guard", ".*");
-					}
-					if(!configAttributes.containsKey("TTLDate")){
-						configAttributes.put("TTLDate", ".*");
-					}
-				}else{
-					// ConfigAttributes is Null. So add basic values. 
-					configAttributes = new HashMap<String,String>();
-					configAttributes.put("RiskType", ".*");
-					configAttributes.put("RiskLevel", ".*");
-					configAttributes.put("guard", ".*");
-					configAttributes.put("TTLDate", ".*");
-				}
-				for (String key : configAttributes.keySet()) {
-					if (key.isEmpty()) {
-						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an empty Key");
-						throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +"Cannot have an empty Key");
-					}
-					JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
-					/*if (configAttributes.get(key).matches("[0-9]+")) {
-						int val = Integer.parseInt(configAttributes.get(key));
-						resourceBuilder.add("Value", val);
-					} else {*/
-					resourceBuilder.add("Value", configAttributes.get(key));
-					resourceBuilder.add("AttributeId", key);
-					resourceArray.add(resourceBuilder);
-				}
-			}else{
-				logger.info("Config Name is not given. ");
-			}
-		}else{
-			logger.info("Ecomp Name is not given. ");
-		}
-		JsonObject model = Json
-				.createObjectBuilder()
-				.add("Request",
-						Json.createObjectBuilder()
-								.add("AccessSubject",
-										Json.createObjectBuilder()
-												.add("Attribute",subjectArray))
-								.add("Action",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														Json.createObjectBuilder()
-																.add("Value",
-																		"ACCESS")
-																.add("AttributeId",
-																		"urn:oasis:names:tc:xacml:1.0:action:action-id")))
-								.add("Resource",
-										Json.createObjectBuilder()
-												.add("Attribute",
-														resourceArray
-																.add(Json
-																		.createObjectBuilder()
-																		.add("Value",
-																				"Config")
-																		.add("AttributeId",
-																				"urn:oasis:names:tc:xacml:1.0:resource:resource-id")))))
-				.build();
-		logger.debug("Generated JSON Request is: " + model.toString());
-		if(listRequestParameters.getUnique()){
-			logger.info("Requested for Unique Result only. ");
-			unique = true;
-		}
-		try {
-			policyConfig = configResult(generateRequest(model.toString(), listRequestParameters.getRequestID()));
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new PolicyConfigException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-		}
+		Collection<PolicyConfig> policyConfig = getConfigImpl(listRequestParameters);
 		for(PolicyConfig policy : policyConfig){
 			if(policy.getPolicyConfigMessage()!=null && policy.getPolicyConfigMessage().contains("PE300")){
 				policyList.add(policy.getPolicyConfigMessage());
@@ -1483,575 +757,58 @@
 		return policyList;
 	}
 	
-
-
-	public Collection<PolicyResponse> event(Map<String, String> eventAttributes, UUID requestID, String userID, String passcode)
-			throws PolicyEventException {
+	public Collection<PolicyResponse> sendEventImpl(Map<String, String> eventAttributes, UUID requestID) throws PolicyEventException {
 		String resource= "sendEvent";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			throw new PolicyEventException(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		Collection<PolicyResponse> policyResponse = null;
-		if (eventAttributes != null && !eventAttributes.isEmpty()) {
-			JsonArrayBuilder resourceArray = Json.createArrayBuilder();
-			for (String key : eventAttributes.keySet()) {
-				if (key.isEmpty()) {
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an Empty Key");
-					throw new PolicyEventException(XACMLErrorConstants.ERROR_DATA_ISSUE +"Cannot have an empty Key");
-				}
-				JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
-				if (eventAttributes.get(key).matches("[0-9]+")) {
-					int val = Integer.parseInt(eventAttributes.get(key));
-					resourceBuilder.add("Value", val);
-				} else {
-					resourceBuilder.add("Value", eventAttributes.get(key));
-				}
-				resourceBuilder.add("AttributeId", key);
-				resourceArray.add(resourceBuilder);
-			}
-			JsonObject model = Json
-					.createObjectBuilder()
-					.add("Request",
-							Json.createObjectBuilder().add(
-									"Resource",
-									Json.createObjectBuilder().add("Attribute",
-											resourceArray))).build();
-			// Removed Part can be Useful in Future.
-			/*
-			 * .add("AccessSubject",Json.createObjectBuilder() .add("Attribute",
-			 * subjectArray)) .add("Action", Json.createObjectBuilder()
-			 * .add("Attribute", actionArray))
-			 */
-			// System.out.println(model.toString());
-			try {
-				// StdPolicyResponse stdPolicyResponse =
-				// generateRequest(model.toString());
-				// stdPolicyResponse.setRequestAttributes(eventAttributes);
-				policyResponse = eventResult(generateRequest(model.toString(), requestID),
-						eventAttributes);
-			} catch (Exception e) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-				throw new PolicyEventException(XACMLErrorConstants.ERROR_DATA_ISSUE +e);
-			}
-		} else {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No event Attributes Given. ");
-			throw new PolicyEventException(XACMLErrorConstants.ERROR_DATA_ISSUE +"No EventAttributes Given.");
-		}
-		return policyResponse;
+        ArrayList<PolicyResponse> response = new ArrayList<PolicyResponse>();
+        String body = new String();
+        // Create Request. 
+        try {
+            // Long way here, can be shortened and will be done. 
+            EventRequestParameters eventRequestParameters = new EventRequestParameters();
+            eventRequestParameters.setEventAttributes(eventAttributes);
+            eventRequestParameters.setRequestID(requestID);
+            body = PolicyUtils.objectToJsonString(eventRequestParameters);
+        } catch (JsonProcessingException e) {
+            String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e; 
+            LOGGER.error(message);
+            throw new PolicyEventException(message, e);
+        }
+        // Get Response. 
+        try {
+            ResponseEntity<StdPolicyResponse[]> result = callNewPDP(resource, HttpMethod.POST, body, StdPolicyResponse[].class);
+            // Process Response
+            response = eventResult(result.getBody());
+        } catch (Exception exception) {
+            if(exception.getCause().getMessage().contains("401")){
+                String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
+                LOGGER.error(message);
+                throw new PolicyEventException(message, exception);
+            }if(exception.getCause().getMessage().contains("400")){
+                String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
+                LOGGER.error(message);
+                throw new PolicyEventException(message, exception);
+            }
+            String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from  PDP(s) " + pdps;
+            LOGGER.error(message, exception);
+            throw new PolicyEventException(message, exception);
+        }
+        return response;
 	}
 
-	private Collection<StdStatus> generateRequest(String Json, UUID requestID) throws Exception {
-		Collection<StdStatus> results = null;
-		
-		Response response = null;
-		// Create Request. We need XACML API here.
-		try {
-			Request request = JSONRequest.load(Json);
-			String jRequest = JSONRequest.toString(request);
-				
-			// Call the PDP
-			logger.debug("--- Generating Request: ---\n" + jRequest );
-			response = callPDP(new ByteArrayInputStream(jRequest.getBytes()), requestID);
+	private ArrayList<PolicyResponse> eventResult(StdPolicyResponse[] response) throws PolicyEventException{
+        ArrayList<PolicyResponse> eventResult = new ArrayList<PolicyResponse>();
+        if(response!=null && response.length>0){
+            for(StdPolicyResponse policyConfigResponse: response){
+                eventResult.add(policyConfigResponse);
+            }
+        }
+        return eventResult;
+    }
 
-		} catch (Exception e) {
-			logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e);
-			StdStatus stdStatus = new StdStatus();
-			results = new HashSet<StdStatus>();
-			stdStatus.setStatus("Unable to Call PDP. Error with the URL",
-					PolicyResponseStatus.NO_ACTION_REQUIRED,
-					PolicyConfigStatus.CONFIG_NOT_FOUND);
-			results.add(stdStatus);
-			throw new Exception(e);
-		}
-
-		if(this.UEBThread){
-			this.UEBThread = registerUEBThread.isAlive();
-		}
-		if (response != null) {
-			results = checkResponse(response);
-			// TODO Starting Auto Client Here.
-			if (notificationType.get(0).equals("ueb") && !this.UEBThread){
-				this.UEBClientThread = new AutoClientUEB(pdps.get(0), uebURLList); 
-				this.registerUEBThread = new Thread(this.UEBClientThread);
-				this.registerUEBThread.start();
-				this.UEBThread = true;
-				
-			}else {
-				if(AutoClientEnd.getURL()==null){
-					AutoClientEnd.start(pdps.get(0));
-				}else if(AutoClientEnd.getURL()!=pdps.get(0)){
-					AutoClientEnd.stop();
-					AutoClientEnd.start(pdps.get(0));
-				}
-			}
-		} else {
-			logger.debug("No Response Received from PDP");
-			StdStatus stdStatus = new StdStatus();
-			results = new HashSet<StdStatus>();
-			stdStatus.setStatus("No Response Received",
-					PolicyResponseStatus.NO_ACTION_REQUIRED,
-					PolicyConfigStatus.CONFIG_NOT_FOUND);
-			results.add(stdStatus);
-		}
-
-		return results;
-	}
-	
-	private Response callPDP(ByteArrayInputStream input, UUID requestID) throws Exception {
-		Response response = null;
-		HttpURLConnection connection = null;
-		responseCode = 0;
-		// Checking for the available PDPs is done during the first Request and
-		// the List is going to have the connected PDP as first element.
-		// This makes it Real-Time to change the list depending on their
-		// availability.
-		if (pdps == null || pdps.isEmpty()) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDPs List is Empty.");
-			throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"PDPs List is empty.");
-		} else {
-			int pdpsCount = 0;
-			boolean connected = false;
-			while (pdpsCount < pdps.size()) {
-				input.reset();
-				try {
-					String urlValue = pdps.get(0);
-					URL url = new URL(urlValue);
-					logger.debug("--- Sending Request to PDP : "+ url.toString() + " ---");
-					connection = (HttpURLConnection) url.openConnection();
-					// Setting Content-Type
-					connection.setRequestProperty("Content-Type","application/json");
-					// Adding Authorization
-					connection.setRequestProperty("Authorization", "Basic "	+ encoding.get(0));
-					// Adding Environment. 
-					connection.setRequestProperty("Environment", environment);
-					// Adding RequestID
-					if (requestID == null) {
-						requestID = UUID.randomUUID();
-						logger.info("No request ID provided, sending generated ID: " + requestID.toString());
-					} else {
-						logger.info("Using provided request ID: " + requestID.toString());
-					}
-					connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
-					// Setting up connection method and headers.
-					connection.setRequestMethod("POST");
-					connection.setUseCaches(false);
-					connection.setInstanceFollowRedirects(false);
-					connection.setDoOutput(true);
-					connection.setDoInput(true);
-					OutputStream os = connection.getOutputStream();
-					IOUtils.copy(input, os);
-					
-					
-					connection.connect();
-					responseCode = connection.getResponseCode();
-					// If Connected to a PDP Then break from the loop and
-					// continue with the Request.
-					if (connection.getResponseCode() == 200 || junit) {
-						connected = true;
-						break;
-					} else {
-						logger.debug(XACMLErrorConstants.ERROR_PERMISSIONS+ "PDP Response Code : "	+ connection.getResponseCode());
-						Collections.rotate(pdps, -1);
-						Collections.rotate(encoding, -1);
-					}
-				} catch (Exception e) {
-					// This means that the PDP is not working and needs to
-					// Re-Order our List and Connect to the next one.
-					logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PDP connection Error : " + e);
-					Collections.rotate(pdps, -1);
-					Collections.rotate(encoding, -1);
-				}
-				pdpsCount++;
-			}
-			if (connected) {
-				// Read the Response
-				// System.out.println("connected to PDP : " + pdps.get(0));
-				logger.debug("connected to PDP : " + pdps.get(0));
-				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 || junit) {
-						// Read the Response
-						ContentType contentType = null;
-						try {
-							contentType = ContentType.parse(connection
-									.getContentType());
-							if (contentType.getMimeType().equalsIgnoreCase(
-									ContentType.APPLICATION_JSON.getMimeType())) {
-								if(junit){
-									response = JSONResponse.load(getJsonResponseString());
-								} else {
-									response = JSONResponse.load(connection.getInputStream());
-								}
-								logger.debug(response + "\n---");
-							} else {
-								logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Unknown Content-Type: "
-										+ contentType);
-								throw new Exception(XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Unknown Content-Type: "
-										+ contentType);
-							}
-						} catch (Exception e) {
-							String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Parsing Content-Type: "
-									+ connection.getContentType() + ", error="
-									+ e;
-							logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e);
-							throw new Exception(message, e);
-						}
-					} else {
-						throw new Exception(XACMLErrorConstants.ERROR_PERMISSIONS+ "ERROR response code of the URL " + pdps.get(0) + " is "
-								+ connection.getResponseCode());
-					}
-				} catch (IOException e) {
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-					throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"Error in Connecting to the  PDP ", e);
-				}
-				return response;
-			} else {
-				if(junit){
-					response = JSONResponse.load(getJsonResponseString());
-					return response;
-				}
-				throw new Exception(XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from  PDP(s) " + pdps);
-			}
-		}
-	}
-	
-	private Collection<StdStatus> checkResponse(Response response)
-			throws Exception {
-
-		String pdpConfigURL = null;
-
-		Collection<StdStatus> combinedResult = new HashSet<StdStatus>();
-		int priority = defaultPriority;
-		Map<Integer, StdStatus> uniqueResult = new HashMap<Integer, StdStatus>();
-		for (Result result : response.getResults()) {
-			if (!result.getDecision().equals(Decision.PERMIT)) {
-				logger.debug("Decision not a Permit. "	+ result.getDecision().toString());
-				StdStatus stdStatus = new StdStatus();
-				if (decide) {
-					stdStatus.setDecision(PolicyDecision.DENY);
-					for(Advice advice: result.getAssociatedAdvice()){
-						for(AttributeAssignment attribute: advice.getAttributeAssignments()){
-							stdStatus.setDetails(attribute.getAttributeValue().getValue().toString());
-							break;
-						}
-					}
-					combinedResult.add(stdStatus);
-					return combinedResult;
-				}
-				stdStatus.setStatus(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Params passed: Decision not a Permit.",PolicyResponseStatus.NO_ACTION_REQUIRED,PolicyConfigStatus.CONFIG_NOT_FOUND);
-				combinedResult.add(stdStatus);
-				return combinedResult;
-			} else {
-				if (decide) {
-					// check for Decision for decision based calls.
-					StdStatus stdStatus = new StdStatus();
-					stdStatus.setDecision(PolicyDecision.PERMIT);
-					stdStatus.setDetails("Decision Permit. OK!");
-					combinedResult.add(stdStatus);
-					return combinedResult;
-				}
-				if (!result.getAssociatedAdvice().isEmpty()) {
-					// @ TODO Add advice actions
-					// Configurations should be in advice. + Also PDP took
-					// actions could be here.
-					for (Advice advice : result.getAssociatedAdvice()) {
-						int config = 0, uri = 0;
-						String configURL = null;
-						String policyName = null;
-						String policyVersion = null;
-						Map<String, String> matchingConditions = new HashMap<String, String>();
-						match = new Matches();
-						Map<String, String> configAttributes = new HashMap<String, String>();
-						Map<String, String> responseAttributes = new HashMap<String,String>();
-						Map<String, String> actionTaken = new HashMap<String, String>();
-						StdStatus stdStatus = new StdStatus();
-						Map<String, String> adviseAttributes = new HashMap<String, String>();
-						for (AttributeAssignment attribute : advice.getAttributeAssignments()) {
-							adviseAttributes.put(attribute.getAttributeId().stringValue(), attribute.getAttributeValue().getValue().toString());
-							if (attribute.getAttributeValue().getValue().toString().equalsIgnoreCase("CONFIGURATION")) {
-								config++;
-							} else if (attribute.getDataTypeId().stringValue().endsWith("anyURI")) {
-								uri++;
-								if (uri == 1) {
-									configURL = attribute.getAttributeValue().getValue().toString();
-									String currentUsedPDP = pdps.get(0);
-									int pos = (pdps.get(0)).lastIndexOf("/");
-									String configURLPath = currentUsedPDP.substring(0, pos);
-									int pos1 = configURLPath.lastIndexOf("/");
-									String pdpConfigURLPath = configURLPath.substring(0, pos1 + 1);
-									pdpConfigURL = configURL.replace("$URL", pdpConfigURLPath);
-								} else {
-									if (!(attribute.getIssuer().equalsIgnoreCase("PDP"))) {
-										throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error having multiple URI in the Policy");
-									}
-								}
-							} else if (attribute.getAttributeId().stringValue()
-									.equalsIgnoreCase("PolicyName")) {
-								policyName = attribute.getAttributeValue()
-										.getValue().toString();
-							} else if (attribute.getAttributeId().stringValue()
-									.equalsIgnoreCase("VersionNumber")) {
-								policyVersion = attribute.getAttributeValue()
-										.getValue().toString();
-							} else if (attribute.getAttributeId().stringValue().equalsIgnoreCase("Priority")){
-								try{
-									priority = Integer.parseInt(attribute.getAttributeValue().getValue().toString());
-								} catch(Exception e){
-									logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE+ "Unable to Parse Integer for Priority. Setting to default value");
-									priority = defaultPriority;
-								}
-							} else if (attribute.getAttributeId().stringValue()
-									.startsWith("matching")) {
-								matchingConditions.put(attribute
-										.getAttributeId().stringValue()
-										.replaceFirst("(matching).", ""),
-										attribute.getAttributeValue()
-												.getValue().toString());
-								if (attribute.getAttributeId().stringValue()
-										.replaceFirst("(matching).", "")
-										.equals("ECOMPName")) {
-									match.setEcompName(attribute
-											.getAttributeValue().getValue()
-											.toString());
-								} else if (attribute.getAttributeId()
-										.stringValue()
-										.replaceFirst("(matching).", "")
-										.equals("ConfigName")) {
-									match.setConfigName(attribute
-											.getAttributeValue().getValue()
-											.toString());
-								} else {
-									configAttributes.put(attribute
-											.getAttributeId().stringValue()
-											.replaceFirst("(matching).", ""),
-											attribute.getAttributeValue()
-													.getValue().toString());
-								}
-							} else if (attribute.getAttributeId().stringValue().startsWith("key:")) {
-								responseAttributes.put(attribute
-										.getAttributeId().stringValue()
-										.replaceFirst("(key).", ""),
-										attribute.getAttributeValue()
-												.getValue().toString());
-							}
-						}
-						if (!configAttributes.isEmpty()) {
-							match.setConfigAttributes(configAttributes);
-						}
-						if ((config == 1) && (uri == 1)) {
-							// If there is a configuration.
-							try {
-								logger.debug("Configuration Call to : "
-										+ configURL);
-								stdStatus = ConfigCall(pdpConfigURL);
-							} catch (Exception e) {
-								logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+ e);
-								stdStatus
-										.setStatus(
-												"Error in Calling the Configuration URL "
-														+ e,
-												PolicyResponseStatus.NO_ACTION_REQUIRED,
-												PolicyConfigStatus.CONFIG_NOT_FOUND);
-							}
-							stdStatus.setPolicyName(policyName);
-							stdStatus.setPolicyVersion(policyVersion);
-							stdStatus.setMatchingConditions(matchingConditions);
-							stdStatus.setResposneAttributes(responseAttributes);
-							if(!unique){
-								combinedResult.add(stdStatus);
-							}else{
-								if(!uniqueResult.isEmpty()){
-									if(uniqueResult.containsKey(priority)){
-										// Not any more unique, check the matching conditions size
-										int oldSize = uniqueResult.get(priority).getMatchingConditions().size();
-										int newSize = matchingConditions.size();
-										if(oldSize < newSize){
-											uniqueResult.put(priority, stdStatus);
-										}else if(oldSize == newSize){
-											stdStatus = new StdStatus();
-											stdStatus.setStatus("Two/more Policies have Same Priority and matching conditions, Please correct your policies.", PolicyResponseStatus.NO_ACTION_REQUIRED,
-													PolicyConfigStatus.CONFIG_NOT_FOUND);
-											combinedResult.add(stdStatus);
-											unique = false;
-											return combinedResult;
-										}
-									}else{
-										uniqueResult.put(priority, stdStatus);
-									}
-								}else{
-									uniqueResult.put(priority, stdStatus);
-								}
-							}
-						} else {
-							// Else it is Action Taken.
-							logger.info("Action Taken by PDP. ");
-							actionTaken.putAll(adviseAttributes);
-							stdStatus.setActionTaken(actionTaken);
-							stdStatus.setPolicyResponseStatus(
-									"Action Taken by the PDP",
-									PolicyResponseStatus.ACTION_TAKEN);
-							combinedResult.add(stdStatus);
-						}
-					}
-				}
-				if (!result.getObligations().isEmpty()) {
-					// @ TODO add Obligation actions
-					// Action advised should be in obligations.
-					for (Obligation obligation : result.getObligations()) {
-						Map<String, String> actionAdvised = new HashMap<String, String>();
-						StdStatus stdStatus = new StdStatus();
-						for (AttributeAssignment attribute : obligation
-								.getAttributeAssignments()) {
-							actionAdvised.put(attribute.getAttributeId()
-									.stringValue(), attribute
-									.getAttributeValue().getValue().toString());
-						}
-						stdStatus.setActionAdvised(actionAdvised);
-						stdStatus.setPolicyResponseStatus(
-								"Action has been Advised ",
-								PolicyResponseStatus.ACTION_ADVISED);
-						combinedResult.add(stdStatus);
-					}
-				}
-			}
-		}
-		if(unique){
-			// Select Unique policy. 
-			int minNum = defaultPriority;
-			for(int num: uniqueResult.keySet()){
-				if(num < minNum){
-					minNum = num;
-				}
-			}
-			combinedResult.add(uniqueResult.get(minNum));
-			// Turn off Unique
-			unique = false;
-		}
-		
-		return combinedResult;
-	}
-
-	private StdStatus ConfigCall(String stringURL) throws Exception {
-		StdStatus stdStatus = new StdStatus();
-		try {
-			URL configURL = new URL(stringURL);
-			URLConnection connection = null;
-			try {
-				connection = configURL.openConnection();
-				if (stringURL.endsWith("json")) {
-					stdStatus.setPolicyType(PolicyType.JSON);
-					JsonReader jsonReader = Json.createReader(connection
-							.getInputStream());
-					stdStatus.setJsonObject(jsonReader.readObject());
-					jsonReader.close();
-					logger.info("config Retrieved ");
-					stdStatus.setStatus("Config Retrieved from: " + configURL,
-							PolicyResponseStatus.NO_ACTION_REQUIRED,
-							PolicyConfigStatus.CONFIG_RETRIEVED);
-					try {
-						MatchStore.storeMatch(match);
-					} catch (Exception e) {
-						logger.info("StoreMatch failed for Ecomp:"
-								+ match.getEcompName() + " Config: "
-								+ match.getConfigName());
-					}
-					return stdStatus;
-				} else if (stringURL.endsWith("xml")) {
-					stdStatus.setPolicyType(PolicyType.XML);
-					DocumentBuilderFactory dbf = DocumentBuilderFactory
-							.newInstance();
-					DocumentBuilder db = null;
-					try {
-						db = dbf.newDocumentBuilder();
-						Document config = db.parse(connection.getInputStream());
-						stdStatus.setDocument(config);
-					} catch (ParserConfigurationException e) {
-						logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e);
-						throw new Exception(XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Unable to create Document Object",
-								e);
-					} catch (SAXException e) {
-						logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ e);
-						throw new Exception(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the XML config", e);
-					}
-					logger.info("config Retrieved ");
-					stdStatus.setStatus("Config Retrieved from: " + configURL,
-							PolicyResponseStatus.NO_ACTION_REQUIRED,
-							PolicyConfigStatus.CONFIG_RETRIEVED);
-					try {
-						MatchStore.storeMatch(match);
-					} catch (Exception e) {
-						logger.info("StoreMatch failed for Ecomp:"
-								+ match.getEcompName() + " Config: "
-								+ match.getConfigName());
-					}
-					return stdStatus;
-				} else if (stringURL.endsWith("properties")) {
-					stdStatus.setPolicyType(PolicyType.PROPERTIES);
-					Properties configProp = new Properties();
-					configProp.load(connection.getInputStream());
-					stdStatus.setProperties(configProp);
-					logger.info("config Retrieved ");
-					stdStatus.setStatus("Config Retrieved from: " + configURL,
-							PolicyResponseStatus.NO_ACTION_REQUIRED,
-							PolicyConfigStatus.CONFIG_RETRIEVED);
-					try {
-						MatchStore.storeMatch(match);
-					} catch (Exception e) {
-						logger.info("StoreMatch failed for Ecomp:"
-								+ match.getEcompName() + " Config: "
-								+ match.getConfigName());
-					}
-					return stdStatus;
-				} else if (stringURL.endsWith("txt")) {
-					stdStatus.setPolicyType(PolicyType.OTHER);
-					InputStream in = connection.getInputStream();
-					String other = IOUtils.toString(in);
-					IOUtils.closeQuietly(in);
-					stdStatus.setOther(other);
-					logger.info("config Retrieved ");
-					stdStatus.setStatus("Config Retrieved from: " + configURL,
-							PolicyResponseStatus.NO_ACTION_REQUIRED,
-							PolicyConfigStatus.CONFIG_RETRIEVED);
-					try {
-						MatchStore.storeMatch(match);
-					} catch (Exception e) {
-						logger.info("StoreMatch failed for Ecomp:"
-								+ match.getEcompName() + " Config: "
-								+ match.getConfigName());
-					}
-					return stdStatus;
-				} else {
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Config Not Found");
-					stdStatus
-							.setPolicyConfigStatus(PolicyConfigStatus.CONFIG_NOT_FOUND);
-					stdStatus
-							.setConfigStatus("Illegal form of Configuration Type Found.");
-					return stdStatus;
-				}
-			} catch (IOException e) {
-				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
-				throw new Exception(XACMLErrorConstants.ERROR_PROCESS_FLOW +
-						"Cannot open a connection to the configURL", e);
-			}
-		} catch (MalformedURLException e) {
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
-			throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in ConfigURL", e);
-		}
-	}
-
-	private void setProperty(String propertyFilePath)
+	private void setProperty(String propertyFilePath, String clientKey)
 			throws PolicyEngineException {
 		this.propertyFilePath = propertyFilePath;
 		if (this.propertyFilePath == null) {
-			// This is only for testing purpose. Or We will add a default PDP
-			// address here.
-			// url_default = "http://localhost:8080/pdp/";
-			// The General Error Message is Below.
 			throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error NO PropertyFile Path provided");
 		} else {
 			// Adding logic for remote Properties file.
@@ -2064,7 +821,7 @@
 					connection = configURL.openConnection();
 					prop.load(connection.getInputStream());
 				} catch (IOException e) {
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
+					LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
 					throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Maformed property URL "+ e.getMessage());
 				}
 			} else {
@@ -2079,24 +836,29 @@
 						in = new FileInputStream(file.toFile());
 						prop.load(in);
 					} catch (IOException e) {
-						logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+						LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
 						throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Cannot Load the Properties file", e);
 					}
 				} else {
-					logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file " + propertyFilePath);
+					LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file " + propertyFilePath);
 					throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR  + "Not a .properties file");
 				}
 			}
-			// UEB Settings
+			// UEB and DMAAP Settings
 			String check_type = prop.getProperty("NOTIFICATION_TYPE");
-			String serverList = prop.getProperty("NOTIFICATION_UEB_SERVERS");
+			String serverList = prop.getProperty("NOTIFICATION_SERVERS");
+			topic = prop.getProperty("NOTIFICATION_TOPIC");
+			apiKey = prop.getProperty("UEB_API_KEY");
+			apiSecret = prop.getProperty("UEB_API_SECRET");
+			
 			if(check_type==null) {
-				notificationType.add("websocket");
-				logger.info("Properties file doesn't have the NOTIFICATION_TYPE parameter system will use defualt websockets");	
+				notificationType.add(DEFAULT_NOTIFICATION);
+				LOGGER.info("Properties file doesn't have the NOTIFICATION_TYPE parameter system will use defualt websockets");	
 			}else{
+				check_type = check_type.trim();
 				if(check_type.contains(",")) {
-					type_default = new ArrayList<String>(Arrays.asList(prop.getProperty("NOTIFICATION_TYPE").split(",")));
-					notificationType = type_default; 
+					typeDefault = new ArrayList<String>(Arrays.asList(prop.getProperty("NOTIFICATION_TYPE").split(",")));
+					notificationType = typeDefault; 
 				} else {
 						notificationType = new ArrayList<String>();
 						notificationType.add(check_type);
@@ -2104,34 +866,53 @@
 			}
 			if(serverList==null) {
 				notificationType.clear();
-				notificationType.add("websocket");
-				logger.info("Properties file doesn't have the NOTIFICATION_UEB_SERVERS parameter system will use defualt websockets");	
+				notificationType.add(DEFAULT_NOTIFICATION);
+				LOGGER.info("Properties file doesn't have the NOTIFICATION_SERVERS parameter system will use defualt websockets");	
 			}else{
+				serverList = serverList.trim();
 				if(serverList.contains(",")) {
-					uebURLList = new ArrayList<String>(Arrays.asList(prop.getProperty("NOTIFICATION_UEB_SERVERS").split(","))); 
+					notificationURLList = new ArrayList<String>(Arrays.asList(serverList.split(","))); 
 				} else {
-					uebURLList = new ArrayList<String>();
-					uebURLList.add(serverList);
+					notificationURLList = new ArrayList<String>();
+					notificationURLList.add(serverList);
 				}
 			}
+			
+			if(topic!=null) {
+				topic = topic.trim();
+			} else {
+				LOGGER.error("Properties file doesn't have the NOTIFICATION_TOPIC parameter.");
+			}
+			
 			// Client ID Authorization Settings. 
 			String clientID = prop.getProperty("CLIENT_ID");
-			String clientKey = prop.getProperty("CLIENT_KEY");
-			userName = clientID;
-			pass = clientKey;
-			pyPDPClientFile = prop.getProperty("CLIENT_FILE");
-			environment = prop.getProperty("ENVIRONMENT", "DEVL");
-			/*try {
-				aafClient = AAFPolicyClient.getInstance(prop);
-			} catch (AAFPolicyException e) {
-				logger.error(XACMLErrorConstants.ERROR_UNKNOWN + e.getMessage());
-				throw new PolicyEngineException(XACMLErrorConstants.ERROR_UNKNOWN + e);
-			}*/
+			if(clientKey==null){
+				clientKey = prop.getProperty("CLIENT_KEY");
+				try {
+					clientKey = PolicyUtils.decode(clientKey);
+				} catch (UnsupportedEncodingException|IllegalArgumentException e) {
+					LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS+" Cannot Decode the given Password Proceeding with given Password!!");
+				}
+			}
+			if(clientID ==null || clientKey == null || clientID.isEmpty() || clientKey.isEmpty()){
+				LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS+" Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
+				throw new PolicyEngineException(XACMLErrorConstants.ERROR_PERMISSIONS+ " Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
+			}else{
+				userName = clientID.trim();
+				pass = clientKey.trim();
+			}
+			setClientEncoding();
+			environment = prop.getProperty("ENVIRONMENT", Environment.DEVL.toString());
+			if(environment.equalsIgnoreCase(Environment.TEST.toString())){
+				environment = Environment.TEST.toString();
+			}else if(environment.equalsIgnoreCase(Environment.PROD.toString())){
+				environment = Environment.PROD.toString();
+			}else{
+				environment = Environment.DEVL.toString();
+			}
 			// Initializing the values.
 			pdps = new ArrayList<String>();
-			paps = new ArrayList<String>(); 
 			encoding = new ArrayList<String>();
-			encodingPAP = new ArrayList<String>();
 			// Check the Keys for PDP_URLs
 			Collection<Object> unsorted = prop.keySet();
 			@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -2144,53 +925,32 @@
 						throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Properties file doesn't have the PDP_URL parameter");
 					}
 					if (check_val.contains(";")) {
-						pdp_default = new ArrayList<String>(Arrays.asList(check_val.split("\\s*;\\s*")));
+						pdpDefault = new ArrayList<String>(Arrays.asList(check_val.split("\\s*;\\s*")));
 						int pdpCount = 0;
-						while (pdpCount < pdp_default.size()) {
-							String pdpVal = pdp_default.get(pdpCount);
+						while (pdpCount < pdpDefault.size()) {
+							String pdpVal = pdpDefault.get(pdpCount);
 							readPDPParam(pdpVal);
 							pdpCount++;
 						}
 					} else {
 						readPDPParam(check_val);
 					}
-				} else if (propKey.startsWith("PAP_URL")) {
-					String check_val = prop.getProperty(propKey);
-					if (check_val == null) {
-						throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Properties file doesn't have the PAP_URL parameter");
-					}
-					if (check_val.contains(";")) {
-						pap_default = new ArrayList<String>(Arrays.asList(check_val.split("\\s*;\\s*")));
-						int papCount = 0;
-						while (papCount < pap_default.size()) {
-							String papVal = pap_default.get(papCount);
-							readPAPParam(papVal);
-							papCount++;
-						}
-					} else {
-						readPAPParam(check_val);
-					}
 				}
 			}
 			if (pdps == null || pdps.isEmpty()) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
+				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
 				throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
 			}
 			
-			if (paps == null || paps.isEmpty()) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PAP_URLs");
-				throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed with out PAP_URLs");
-			}
-			
 			// Get JUNIT property from properties file when running tests
 			String junit = prop.getProperty("JUNIT");
 			if(junit == null || junit.isEmpty()){
-				logger.info("No JUNIT property provided, this will not be executed as a test.");
+				LOGGER.info("No JUNIT property provided, this will not be executed as a test.");
 			}else{
-				if(junit.equals("test")){
-					this.junit = true;
+				if(junit.equalsIgnoreCase("test")){
+					StdPolicyEngine.junit = true;
 				} else {
-					this.junit = false;
+					StdPolicyEngine.junit = false;
 				}
 			}
 		}
@@ -2211,65 +971,55 @@
 				Base64.Encoder encoder = Base64.getEncoder();
 				encoding.add(encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8)));
 			}else{
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + pdpValues);
+				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + pdpValues);
 				throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No enough Credentials to send Request. " + pdpValues);
 			}
 		}else{
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values: " + pdpVal);
+			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values: " + pdpVal);
 			throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values.");
 		}
 	}
-	
-	/*
-	 * Read the PAP_URL parameter
-	 */
-	private void readPAPParam(String papVal) throws PolicyEngineException{
-		if(papVal.contains(",")){
-			List<String> papValues = new ArrayList<String>(Arrays.asList(papVal.split("\\s*,\\s*")));
-			if(papValues.size()==3){
-				// 0 - PAPURL
-				paps.add(papValues.get(0));
-				// 1:2 will be UserID:Password
-				String userID = papValues.get(1);
-				String pass = papValues.get(2);
-				Base64.Encoder encoder = Base64.getEncoder();
-				encodingPAP.add(encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8)));
-			}else{
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + papValues);
-				throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No enough Credentials to send Request. " + papValues);
-			}
-		}else{
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + papVal);
-			throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No enough Credentials to send Request.");
-		}
-	}
 	/*
 	 * Allowing changes to the scheme and Handler.
 	 */
 	public void notification(NotificationScheme scheme, NotificationHandler handler) {
 		this.scheme = scheme;
 		this.handler = handler;
-		logger.debug("Scheme is : " + scheme.toString());
-		logger.debug("Handler is : " + handler.getClass().getName());
-		if (!notificationType.get(0).equals("ueb")){
+		LOGGER.debug("Scheme is : " + scheme.toString());
+		LOGGER.debug("Handler is : " + handler.getClass().getName());
+				
+		if (notificationType.get(0).equals("ueb")){
+			if (this.uebThread) {
+				uebClientThread.setAuto(scheme, handler);
+				this.uebThread = registerUEBThread.isAlive();
+			}
+		} else if (notificationType.get(0).equals("dmaap")){
+			if (this.dmaapThread) {
+				dmaapClientThread.setAuto(scheme, handler);
+				this.dmaapThread = registerDMAAPThread.isAlive();
+			}
+		} else {
 			AutoClientEnd.setAuto(scheme, handler);
-		}else {
-			if (this.UEBThread){
-				UEBClientThread.setAuto(scheme, handler);
-				this.UEBThread = registerUEBThread.isAlive();
-			}
 		}
-	
-		//TODO This could also be a Start point for Auto Notifications..
+		
+		if(junit){
+		    return;
+		}
+		
 		if(pdps!=null){
-			if (notificationType.get(0).equals("ueb")  && !this.UEBThread){
-				this.UEBClientThread = new AutoClientUEB(pdps.get(0), uebURLList); 
-				this.UEBClientThread.setAuto(scheme, handler);
-				this.registerUEBThread = new Thread(this.UEBClientThread);
+			if (notificationType.get(0).equals("ueb")  && !this.uebThread){
+				this.uebClientThread = new AutoClientUEB(pdps.get(0), notificationURLList, apiKey, apiSecret); 
+				this.uebClientThread.setAuto(scheme, handler);
+				this.registerUEBThread = new Thread(this.uebClientThread);
 				this.registerUEBThread.start();
-				this.UEBThread = true;
-			}
-			if (!notificationType.get(0).equals("ueb")){
+				this.uebThread = true;
+			}else if (notificationType.get(0).equals("dmaap") && !this.dmaapThread){
+				this.dmaapClientThread = new AutoClientDMAAP(notificationURLList,topic,userName,pass);
+				this.dmaapClientThread.setAuto(scheme, handler);
+				this.registerDMAAPThread = new Thread(this.dmaapClientThread);
+				this.registerDMAAPThread.start();
+				this.dmaapThread = true;
+			}else{
 				if(pdps.get(0)!=null){
 					if(AutoClientEnd.getURL()==null){
 						AutoClientEnd.start(pdps.get(0));
@@ -2287,26 +1037,26 @@
 	 * purposes.
 	 */
 	public PDPNotification getNotification(){
-		//TODO manual Polling
 		//Check if there is proper scheme.. 
 		PDPNotification notification = null;
 		if(this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS) || this.scheme.equals(NotificationScheme.MANUAL_NOTIFICATIONS)) {
 			if (notificationType.get(0).equals("ueb")){
-				ManualClientEndUEB.start(pdps.get(0), uebURLList, uniqueID);
+				ManualClientEndUEB.start(pdps.get(0), notificationURLList, UNIQUEID);
 				notification = ManualClientEndUEB.result(scheme);
+			}else if (notificationType.get(0).equals("dmaap")){
+				ManualClientEndDMAAP.start(notificationURLList, topic, UNIQUEID, userName, pass);
+				notification = ManualClientEndDMAAP.result(scheme);
 			}else{
 				ManualClientEnd.start(pdps.get(0));
-				logger.debug("manual notification requested.. : " + scheme.toString());
+				LOGGER.debug("manual notification requested.. : " + scheme.toString());
 				notification = ManualClientEnd.result(scheme);
 			}
-			
 			if (notification == null){
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Notification yet..");
+				LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Notification yet..");
 				return null;
 			} else {
 				return notification;
 			}
-			
 		}else {
 			return null;
 		}
@@ -2320,7 +1070,12 @@
 		if (notificationType.get(0).equals("ueb")){
 			AutoClientUEB.setScheme(this.scheme);
 			if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)){
-				ManualClientEndUEB.createTopic(pdps.get(0), uniqueID, uebURLList);
+				ManualClientEndUEB.createTopic(pdps.get(0), UNIQUEID, notificationURLList);
+			}
+		}else if (notificationType.get(0).equals("dmaap")){
+			AutoClientDMAAP.setScheme(this.scheme);
+			if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)){
+				ManualClientEndDMAAP.createTopic(topic, UNIQUEID, notificationURLList, userName, pass);
 			}
 		}else{
 			AutoClientEnd.setScheme(this.scheme);
@@ -2341,54 +1096,6 @@
 		return this.handler;
 	}
 
-	private Collection<PolicyConfig> configResult(
-			Collection<StdStatus> generateRequest) {
-		Collection<PolicyConfig> result = new HashSet<PolicyConfig>();
-		if (generateRequest == null) {
-			return null;
-		}
-		if (!generateRequest.isEmpty()) {
-			for (StdStatus stdStatus : generateRequest) {
-				PolicyConfig policyConfig = new StdPolicyConfig();
-				policyConfig = stdStatus;
-				result.add(policyConfig);
-			}
-		}
-		return result;
-	}
-
-	private Collection<PolicyResponse> eventResult(
-			Collection<StdStatus> generateRequest,
-			Map<String, String> eventAttributes) {
-		Collection<PolicyResponse> result = new HashSet<PolicyResponse>();
-		if (generateRequest == null) {
-			return null;
-		}
-		if (!generateRequest.isEmpty()) {
-			for (StdStatus stdStatus : generateRequest) {
-				StdPolicyResponse policyResponse = new StdPolicyResponse();
-				policyResponse = stdStatus;
-				policyResponse.setRequestAttributes(eventAttributes);
-				result.add(policyResponse);
-			}
-		}
-		return result;
-	}
-
-	private DecisionResponse decisionResult(Collection<StdStatus> generateRequest) {
-		StdDecisionResponse policyDecision = new StdDecisionResponse();
-		if (generateRequest == null) {
-			return policyDecision;
-		}
-		if (!generateRequest.isEmpty()) {
-			for (StdStatus stdStatus : generateRequest) {
-				policyDecision.setDecision(stdStatus.getDecision());
-				policyDecision.setDetails(stdStatus.getDetails());
-			}
-		}
-		return policyDecision;
-	}
-
 	/*
 	 * Stop the Notification Service if its running.
 	 */
@@ -2397,10 +1104,13 @@
 			if (this.scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)
 					|| this.scheme
 							.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
-				logger.info("Clear Notification called.. ");
+				LOGGER.info("Clear Notification called.. ");
 				if (notificationType.get(0).equals("ueb")){
-					this.UEBClientThread.terminate();
-					this.UEBThread = false;
+					this.uebClientThread.terminate();
+					this.uebThread = false;
+				}else if (notificationType.get(0).equals("dmaap")){
+					this.dmaapClientThread.terminate();
+					this.dmaapThread = false;
 				}else{
 					AutoClientEnd.stop();
 				}
@@ -2409,1819 +1119,138 @@
 	}
 	
 	/*
-	 * Create Config Policy API Implementation
-	 */
-	public String createConfigPolicy(String policyName, String policyDescription, String ecompName, String configName,
-			Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		return createConfigPolicy(policyName,policyDescription, ecompName, configName,
-				configAttributes, configType, body, policyScope, requestID, userName , pass, riskLevel, riskType, guard, ttlDate);
-	}
-	
-	public String createConfigPolicy(String policyName, String policyDescription, String ecompName, String configName,
-										Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID, String userID, String passcode,
-										String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = null;
-		String configBody = null;
-		String resource= "createPolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response = XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource;
-			return response;
-		}
-		
-		//check body for JSON form and remove single quotes if present
-		if (configType.equalsIgnoreCase("JSON")) {
-			if (body.contains("'")) {
-				configBody = body.replace("'", "\"");
-			} else {
-				configBody = body;
-			}
-		} else {
-			configBody = body;
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.";
-		} else if (configName==null||configName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Config Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Config Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		}else {
-
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("Base", policyName, policyDescription, ecompName, configName, configAttributes, configType, 
-				configBody, false, policyScope,0, riskLevel, riskType, guard, ttlDate);
-
-			//send JSON object to PAP
-			response = (String) callPAP(newPAPPolicy, new String[] {"operation=create", "apiflag=api", "policyType=Config"}, requestID, "Config");
-		}
-		return response;
-
-	}
-	
-	/*
-	 * Create Config Policy API Implementation
-	 */
-	public String updateConfigPolicy(String policyName, String policyDescription, String ecompName, String configName,
-			Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		return updateConfigPolicy(policyName, policyDescription, ecompName, configName,
-				configAttributes, configType, body, policyScope, requestID, userName, pass, riskLevel, riskType, guard, ttlDate);
-	}
-	
-	public String updateConfigPolicy(String policyName, String policyDescription, String ecompName, String configName,
-										Map<String, String> configAttributes, String configType, String body, String policyScope, 
-										UUID requestID, String userID, String passcode,String riskLevel, String riskType, String guard, 
-										String ttlDate) throws Exception {
-		
-		String response = null;
-		String configBody = null;
-		String resource= "updatePolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response = XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource;
-			return response;
-		}
-		//check body for JSON form and remove single quotes if present
-		if (configType.equalsIgnoreCase("JSON")) {
-			if (body.contains("'")) {
-				configBody = body.replace("'", "\"");
-			} else {
-				configBody = body;
-			}
-		} else {
-			configBody = body;
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.";
-		} else if (configName==null||configName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Config Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Config Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-
-			//set values for basic policy information
-			String policyType = "Config";
-			String configPolicyType = "base";
-
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy(configPolicyType, policyName, policyDescription, ecompName, configName, configAttributes, configType, 
-				configBody, true, policyScope,0, riskLevel, riskType, guard, ttlDate);
-
-			//send JSON object to PAP
-			response = (String) callPAP(newPAPPolicy, new String[] {"operation=update", "apiflag=api", "policyType=" + policyType}, requestID, "Config");
-		
-		}
-		return response;
-
-	}
-	
-	
-	/*
-	 * Create Config Firewall Policy API implementation
-	 */
-	public String createConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		return createConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID, userName, pass, riskLevel, riskType, guard, ttlDate);
-	}
-	
-	public String createConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID, String userID, String passcode,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {		
-       		
-		String response = null;
-		String resource= "createPolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response = XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource;
-			return response;
-		}
-		
-		//set values for basic policy information
-		String configName = firewallJson.get("configName").toString();
-        //String configDescription = firewallJson.get("configDescription").toString();
-		String configDescription = "";
-		String json = firewallJson.toString();
-		
-		boolean levelCheck = isNumeric(riskLevel);
-
-		if (!isJSONValid(json)) {
-			logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Invalid JSON for firewallJson: " + json);
-			throw new PolicyDecisionException(XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Invalid JSON for firewallJson: " + json);
-		}
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("Firewall Config", policyName, configDescription, configName, false, policyScope, json, 0, 
-					riskLevel, riskType, guard, ttlDate);
-			
-			//send JSON object to PAP
-			response = (String) callPAP(newPAPPolicy, new String[] {"operation=create", "apiflag=api", "policyType=Config"}, requestID, "ConfigFirewall");
-		}
-
-		return response;
-	} 
-	
-	/*
-	 * Update Config Firewall Policy API implementation
-	 */
-	public String updateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID, String riskLevel, String riskType, 
-			String guard, String ttlDate) throws Exception {
-		return updateConfigFirewallPolicy(policyName, firewallJson, policyScope, requestID, userName, pass, riskLevel, riskType, guard, ttlDate);
-	}
-	
-	public String updateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID, String userID, String passcode,
-			String riskLevel, String riskType, String guard, String ttlDate) throws Exception {
-		
-		String response = null;
-		String resource= "updatePolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response = XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource;
-			return response;
-		}
-		String configName = firewallJson.get("configName").toString();
-	    //String configDescription = firewallJson.get("configDescription").toString();
-		String configDescription = "";  //ASK Lak about this...****
-		String json = firewallJson.toString();
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("Firewall Config", policyName, configDescription, configName, true, policyScope, json, 0,
-														  riskLevel, riskType, guard, ttlDate);
-		
-			//send JSON object to PAP
-			response = (String) callPAP(newPAPPolicy, new String[] {"operation=update", "apiflag=api", "policyType=Config"}, requestID, "ConfigFirewall");
-		}
-		
-		return response;
-	}
-	
-	/*
-	 * Create or Update BRMS Raw Config Policy API implementation
-	 */
-	public String createUpdateBRMSRawPolicy(String policyName, 
-			String policyDescription, 
-			Map<AttributeType, Map<String, String>>  dyanamicFieldConfigAttributes,
-			String brmsRawBody, 
-			String policyScope, 
-			Boolean isEdit, 
-			UUID requestID,
-			String riskLevel, 
-			String riskType, 
-			String guard, 
-			String ttlDate) {
-		
-		String response = null;
-		String operation = null;
-		
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if(policyDescription==null || policyDescription.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policyDescription given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No policyDescription given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (brmsRawBody==null ||brmsRawBody.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No rule body given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No rule body given.";
-		}  else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			/*String configPolicyType, String policyName, String description, 
-					String configName, Boolean editPolicy, String domain, 
-					Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
-					String configBodyData*/
-			
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("BRMS_Raw",policyName,policyDescription,
-															"BRMS_RAW_RULE",isEdit,policyScope, 
-															dyanamicFieldConfigAttributes.get(AttributeType.RULE), 0, "DROOLS", 
-															brmsRawBody, riskLevel, riskType, guard, ttlDate);
-		
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, requestID, "ConfigBrmsRaw");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		
-		return response;
-	}
-	
-	/*
-	 * Create or Update BRMS Param Config Policy API implementation
-	 */
-	public String createUpdateBRMSParamPolicy(String policyName, 
-			String policyDescription, 
-			Map<AttributeType, Map<String, String>>  dyanamicFieldConfigAttributes,
-			String brmsRawBody, 
-			String policyScope, 
-			Boolean isEdit, 
-			UUID requestID,
-			Map<AttributeType, Map<String, String>> drlRuleAndUIParams,
-			String riskLevel, String riskType, String guard, String ttlDate) {
-		
-		String response = null;
-		String operation = null;
-		
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if(policyDescription==null || policyDescription.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No policyDescription given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No policyDescription given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if ((dyanamicFieldConfigAttributes==null)){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Rule Attributes given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Rule Attributes given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		}else {
-			/*public StdPAPPolicy (String configPolicyType, String policyName, String description, 
-					String configName, Boolean editPolicy, String domain, 
-					Map<String,String> dyanamicFieldConfigAttributes, Integer highestVersion, String eCompName, 
-					String configBodyData,Map<String,String> drlRuleAndUIParams) */
-			
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("BRMS_Param",policyName,policyDescription,
-															"BRMS_PARAM_RULE",isEdit,policyScope, 
-															drlRuleAndUIParams.get(AttributeType.MATCHING), 0, "DROOLS", 
-															brmsRawBody, drlRuleAndUIParams.get(AttributeType.RULE), riskLevel, riskType, guard, ttlDate);
-		
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, requestID, "ConfigBrmsParam");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		
-		return response;
-	}
-	
-	/*
-	 * Create or Update Action Policy API implementation
-	 */
-	public String createUpdateActionPolicy(String policyName, String policyDescription, Map<String,String> componentAttributes, List<String> dynamicRuleAlgorithmLabels,
-								List<String> dynamicRuleAlgorithmField1, List<String> dynamicRuleAlgorithmFunctions, List<String> dynamicRuleAlgorithmField2,
-								String actionPerformer, String actionAttribute, String policyScope, Boolean isEdit, UUID requestID) {
-		
-		String response = null;
-		String operation = null;
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-			return response;
-		} else if (componentAttributes==null||componentAttributes.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Component Attributes given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Component Attributes given.";
-			return response;
-		} else if (actionAttribute==null||actionAttribute.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Action Attribute given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Action Attribute given.";
-			return response;
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-			return response;
-		} else if (actionPerformer==null||actionPerformer.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Action Performer given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Action Performer given.";
-			return response;
-		} else if (!actionPerformer.equals("PEP")) {
-			if (!actionPerformer.equals("PDP")) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Action Performer given.");
-				response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Action Performer given.";
-				return response;
-			}
-		}
-		
-		StdPAPPolicy newPAPPolicy = new StdPAPPolicy(policyName, policyDescription, componentAttributes, dynamicRuleAlgorithmLabels, dynamicRuleAlgorithmFunctions, 
-					dynamicRuleAlgorithmField1, dynamicRuleAlgorithmField2, actionPerformer, actionAttribute, isEdit, policyScope, 0);
-
-			//send JSON object to PAP
-		try {
-			response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Action"}, requestID, "Action");
-		} catch (Exception e) {
-				// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-			
-		return response;
-
-	}
-	
-	/*
-	 * Create or Update Decision Policy implementation
-	 */
-	private String createUpdateDecisionPolicy(String policyName, String policyDescription, String ecompName, RuleProvider ruleProvider, Map<String,String> componentAttributes, Map<String,String> settings,
-			List<String> dynamicRuleAlgorithmLabels, List<String> dynamicRuleAlgorithmField1, List<String> dynamicRuleAlgorithmFunctions, List<String> dynamicRuleAlgorithmField2,
-			String policyScope, Boolean isEdit, UUID requestID) {
-		
-		String response = null;
-		String operation = null;
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No ECOMP Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else {
-			
-			if (ruleProvider==null) {
-				ruleProvider = RuleProvider.CUSTOM ;
-			}
-			
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy(policyName, policyDescription, ecompName, ruleProvider.toString(), componentAttributes, settings, dynamicRuleAlgorithmLabels, dynamicRuleAlgorithmFunctions, 
-									dynamicRuleAlgorithmField1, dynamicRuleAlgorithmField2, null, null, null, isEdit, policyScope, 0);
-		
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Decision"}, requestID, "Decision");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		
-		return response;
-	}
-	
-	/*
-	 * Create or Update ClosedLoop_Fault policy implementation
-	 */
-	private String createUpdateClosedLoopPolicy(String policyName, JsonObject configBody, String policyDescription, String policyScope, Boolean isEdit, 
-			UUID requestID,String riskLevel, String riskType, String guard, String ttlDate) {
-		
-		String response = null;
-		String operation = null;
-		String oldPolicyName = null;
-		
-		if (isEdit){
-			operation = "update";
-			if (policyName.endsWith("_Draft")) {
-				oldPolicyName = policyName + "_Draft.1";
-			}
-		} else {
-			operation = "create";
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		// get values and attributes from the JsonObject
-		String ecompName = configBody.get("ecompname").toString().replace("\"", "");
-		String jsonBody = configBody.toString();
-
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			
-
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("ClosedLoop_Fault", policyName, policyDescription, ecompName, 
-					jsonBody, false, oldPolicyName, null, isEdit, policyScope, 0, riskLevel, riskType, guard, ttlDate); 
-
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, requestID, "ConfigClosedLoop");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-
-		return response;
-		
-	}
-	
-	private String createUpdateClosedLoopPmPolicy(String policyName, JsonObject configBody, String policyDescription, String policyScope, Boolean isEdit, 
-			UUID requestID, String riskLevel, String riskType, String guard, String ttlDate) {
-		
-		String response = null;
-		String operation = null;
-		String oldPolicyName = null;
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		// get values and attributes from the JsonObject
-		String ecompName = configBody.get("ecompname").toString().replace("\"", "");
-		String serviceType = configBody.get("serviceTypePolicyName").toString().replace("\"", "");
-		String jsonBody = configBody.toString();
-
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			
-
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("ClosedLoop_PM", policyName, policyDescription, ecompName, 
-					jsonBody, false, oldPolicyName, serviceType, isEdit, policyScope, 0, riskLevel, riskType, guard, ttlDate); 
-
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, requestID, "ConfigClosedLoop");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-
-		return response;
-		
-	}
-	
-	public Boolean validateNONASCIICharactersAndAllowSpaces(Object json){
-		Boolean isValidForm = false;
-		if (json instanceof String) {
-			String jsonString = (String)json;
-			if (jsonString.isEmpty()) {
-				logger.info("JSON String is empty so cannot validate NON ACSII Characters.");
-			} else {
-				if(CharMatcher.ASCII.matchesAllOf((CharSequence) jsonString)){
-					logger.info("The Value does not contain ASCII Characters");
-				   	 isValidForm = true;
-				}else{
-					logger.error("The Value Contains Non ASCII Characters");
-					isValidForm = false;
-				}	
-			}
-		} else if (json instanceof JsonObject) {
-			JsonObject jsonObj = (JsonObject)json;
-			if (jsonObj.isEmpty()){
-				logger.info("JSON object is empty so cannot validate NON ACSII Characters.");
-			} else {
-				if(CharMatcher.ASCII.matchesAllOf((CharSequence) jsonObj.toString())){
-					logger.info("The Value does not contain ASCII Characters");
-				   	 isValidForm = true;
-				}else{
-					logger.error("The Value Contains Non ASCII Characters");
-					isValidForm = false;
-				}	
-			}
-			
-		}
-		
-		return isValidForm;
-	}
-	
-	private String createUpdateMicroServicesPolicy(String policyName, JsonObject microServiceAttributes, String ecompName, String policyScope, Boolean isEdit, UUID requestID,
-			String riskLevel, String riskType, String guard, String ttlDate) {
-		
-		String response = null;
-		String operation = null;
-		
-		if (isEdit){
-			operation = "update";
-		} else {
-			operation = "create";
-		}
-		
-		boolean levelCheck = isNumeric(riskLevel);
-		
-		// get values and attributes from the JsonObject
-		String microService = microServiceAttributes.get("service").toString().replace("\"", "");
-		String uuid = microServiceAttributes.get("uuid").toString().replace("\"", "");
-		String msLocation = microServiceAttributes.get("location").toString().replace("\"", "");;
-		String policyDescription = microServiceAttributes.get("description").toString().replace("\"", "");
-		String configName = microServiceAttributes.get("configName").toString().replace("\"", "");
-		String priority = microServiceAttributes.get("priority").toString().replace("\"", "");
-		String version = microServiceAttributes.get("version").toString().replace("\"", "");
-
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (ecompName==null||ecompName.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Ecomp Name given.";
-		} else if (configName==null||configName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Configuration Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Configuration Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (!levelCheck){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect Risk Level given.";
-		} else {
-			
-
-			StdPAPPolicy newPAPPolicy = new StdPAPPolicy("DCAE Micro Service", policyName, policyDescription, ecompName, 
-							configName, microService, uuid, msLocation, microServiceAttributes.toString(), priority, 
-							version, isEdit, policyScope, 0, riskLevel, riskType, guard, ttlDate); 
-
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, requestID, "ConfigMS");
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-
-		return response;
-		
-	}
-	
-	
-	/*
 	 * Push a policy to the PDP API implementation
 	 */
-	public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID) throws Exception {
-		return pushPolicy(policyScope, policyName, policyType, pdpGroup, requestID, userName, pass);
+	public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID) throws PolicyException {
+		PushPolicyParameters pushPolicyParameters = new PushPolicyParameters();
+		if(policyScope==null|| policyScope.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
+		}
+		if(policyName==null|| policyName.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
+		}
+		pushPolicyParameters.setPolicyName(policyScope+"."+policyName);
+		pushPolicyParameters.setPolicyType(policyType);
+		pushPolicyParameters.setPdpGroup(pdpGroup);
+		pushPolicyParameters.setRequestID(requestID);
+		return pushPolicyImpl(pushPolicyParameters).getResponseMessage();
 	}
 	
-	public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID, String userID, String passcode) throws Exception {
-		String resource= "pushPolicy";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			return (XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-		}
-		String response = null;
-		String filePrefix = null;
-		String clientScope = null;
-		String activeVersion = null;
-		
-		//get the client scope based policy type
-		if (policyType.equalsIgnoreCase("Firewall")){
-			clientScope = "ConfigFirewall";
-			filePrefix = "Config_FW_";
-		} else if (policyType.equalsIgnoreCase("Action")) {
-			clientScope = "Action";
-			filePrefix = "Action_";
-		} else if (policyType.equalsIgnoreCase("Decision")){
-			clientScope = "Decision";
-			filePrefix = "Decision_";
-		} else if (policyType.equalsIgnoreCase("Base")){
-			clientScope = "Config";
-			filePrefix = "Config_";
-		} else if (policyType.equalsIgnoreCase("ClosedLoop_Fault")){
-			clientScope = "ConfigClosedLoop";
-			filePrefix = "Config_Fault_";
-		} else if (policyType.equalsIgnoreCase("ClosedLoop_PM")){
-			clientScope = "ConfigClosedLoop";
-			filePrefix = "Config_PM_";
-		} else if (policyType.equalsIgnoreCase("MicroService")) {
-			clientScope = "ConfigMS";
-			filePrefix = "Config_MS_";
-		}else if (policyType.equalsIgnoreCase("BRMS_RAW")){
-			clientScope = "ConfigBrmsRaw";
-			filePrefix = "Config_BRMS_Raw_";
-		} else if (policyType.equalsIgnoreCase("BRMS_PARAM")){
-			clientScope = "ConfigBrmsParam";
-			filePrefix = "Config_BRMS_Param_";
-		} else {
-			clientScope = null;
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + policyType + " is not a valid Policy Type.");
-			return XACMLErrorConstants.ERROR_DATA_ISSUE + policyType + " is not a valid Policy Type.";
-		}
-		
-		logger.debug("clientScope is " + clientScope);
-		logger.debug("filePrefix is " + filePrefix);
-		
-		if (pdpGroup == null) {
-			pdpGroup = "default";
-		}
-		
-		if (policyName==null||policyName.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (policyScope==null||policyScope.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
-		} else if (policyType==null||policyType.equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Type given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Type given.";
-		} else {
-			// requestID null check. 
-			if(requestID==null){
-				requestID =  UUID.randomUUID();
-				logger.debug("Request ID not provided.  Generating request ID " + requestID.toString());
-			}
-
-			// change call to getActiveVersion to pass requestID for PAP to receive on the GET process so PAP won't generate another 
-	//		activeVersion = getActiveVersion(policyScope, filePrefix, policyName, clientScope);
-			activeVersion = getActiveVersion(policyScope, filePrefix, policyName, clientScope, requestID);
-			logger.debug("The active version of " + policyScope + File.separator + filePrefix + policyName + " is " + activeVersion);
-			
-			String id = null;
-			if (activeVersion.equalsIgnoreCase("pe100")) {
-				logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is 403. PEP is not Authorized for making this Request!! "
-						+ "\n Contact Administrator for this Scope. ");
-				return XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is 403. PEP is not Authorized for making this Request!! "
-						+ "Contact Administrator for this Scope. ";
-						
-			} else if (activeVersion.equalsIgnoreCase("pe300")) {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is 404.  "
-						+ "This indicates a problem with getting the version from the PAP or the policy does not exist.");
-				return XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is 404.  "
-						+ "This indicates a problem with getting the version from the PAP or the policy does not exist.";
-			}
-			
-			
-			if (!activeVersion.equalsIgnoreCase("0")) {
-				id = policyScope + "." + filePrefix + policyName + "." + activeVersion + ".xml";
-				logger.debug("The policyId is " + id);
-			} else {
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "could not retrieve the activeVersion for this policy.  "
-						+ "This indicates the policy does not exist, please verify the policy exists.");
-				return XACMLErrorConstants.ERROR_DATA_ISSUE + "could not retrieve the activeVersion for this policy. could not retrieve the activeVersion for this policy.  "
-						+ "This indicates the policy does not exist, please verify the policy exists.";
-			}
-
-			// change call to getgitPath to pass requestID for PAP to receive on the GET process so PAP won't generate another 
-			// String gitPath = getGitPath(policyScope, filePrefix, policyName, activeVersion, clientScope);
-			String gitPath = getGitPath(policyScope, filePrefix, policyName, activeVersion, clientScope, requestID);
-			logger.debug("Full gitPath policy xml file: " + gitPath);
-
-			// change call to getSelectedURI to pass requestID for PAP to receive on the GET process so PAP won't generate another 
-			// URI selectedURI = getSelectedURI(gitPath, clientScope);
-			URI selectedURI = getSelectedURI(gitPath, clientScope, requestID);
-			
-			logger.debug("The selectedURI is : " + selectedURI.toString());
-			String name = filePrefix+policyName;
-					
-			StdPDPPolicy selectedPolicy = new StdPDPPolicy(id, true, name, selectedURI, isValid, policyId, description, pushVersion);
-			
-			logger.debug("StdPDPPolicy object contains: " + selectedPolicy.getId() + ", " + selectedPolicy.getName() + ", " + selectedPolicy.getLocation().toString());
-			
-			response = copyPolicy(selectedPolicy, pdpGroup, clientScope, requestID);
-			
-			logger.debug("copyPolicy response:  " + response);
-			
-			if(response.contains("successfully")){
-				response = (String) callPAP(selectedPolicy, new String[]{"groupId=" + pdpGroup, "policyId="+id, "apiflag=addPolicyToGroup", "operation=PUT"}, requestID, clientScope);
-			}
-			
-			logger.debug("Final API response: " + response);
-		}
-		
-		return response;
-		
-	}
-	
-	private String deletePolicyFromPAP(DeletePolicyParameters parameters) {
-		String response = null;
-		String clientScope = null;
-		String pdpGroup = parameters.getPdpGroup();
-		
-		if (pdpGroup==null){
-			pdpGroup="NA";
-		}
-		
-		//get the client scope based policy type
-		if (parameters.getPolicyName().contains("Config_FW")){
-			clientScope = "ConfigFirewall";
-		} else if (parameters.getPolicyName().contains("Action")) {
-			clientScope = "Action";
-		} else if (parameters.getPolicyName().contains("Decision")){
-			clientScope = "Decision";
-		} else if (parameters.getPolicyName().contains("Config_Fault")){
-			clientScope = "ConfigClosedLoop";
-		} else if (parameters.getPolicyName().contains("Config_PM")){
-			clientScope = "ConfigClosedLoop";
-		} else if (parameters.getPolicyName().contains("Config_MS")){
-			clientScope = "ConfigMS";
-		} else if (parameters.getPolicyName().contains("Config_BRMS_Raw")){
-			clientScope = "ConfigBrmsRaw";
-		} else if (parameters.getPolicyName().contains("Config_BRMS_Param")){
-			clientScope = "ConfigBrmsParam";
-		} else {
-			clientScope = "Config";
-		}
-		
-		logger.debug("clientScope is " + clientScope);
-		
-		if (clientScope==null||clientScope.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + parameters.getPolicyName() + " is not a valid Policy Name.");
-			return XACMLErrorConstants.ERROR_DATA_ISSUE + parameters.getPolicyName() + " is not a valid Policy Name.";
-		}
-		
-		if (parameters.getPolicyName()==null||parameters.getPolicyName().equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (parameters.getDeleteCondition()==null||parameters.getDeleteCondition().equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Delete Condition given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Delete Condition given.";
-		} else {
-			
-			StdPAPPolicy deletePapPolicy = new StdPAPPolicy(parameters.getPolicyName(), parameters.getDeleteCondition().toString()); 
-
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(deletePapPolicy, new String[] {"groupId="+pdpGroup, "apiflag=deletePapApi", "operation=delete" }, parameters.getRequestID(), clientScope);
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}		
-			
-		}
-		
-		return response;
-	}
-	
-	private String deletePolicyFromPDP(DeletePolicyParameters parameters) {
-		String response = null;
-		String clientScope = null;
-		String pdpGroup = parameters.getPdpGroup();
-		
-		if (pdpGroup==null){
-			pdpGroup="NA";
-		}
-		
-		//get the client scope based policy type
-		if (parameters.getPolicyName().contains("Config_FW")){
-			clientScope = "ConfigFirewall";
-		} else if (parameters.getPolicyName().contains("Action")) {
-			clientScope = "Action";
-		} else if (parameters.getPolicyName().contains("Decision")){
-			clientScope = "Decision";
-		} else if (parameters.getPolicyName().contains("Config_Fault")){
-			clientScope = "ConfigClosedLoop";
-		} else if (parameters.getPolicyName().contains("Config_PM")){
-			clientScope = "ConfigClosedLoop";
-		} else if (parameters.getPolicyName().contains("Config_MS")){
-			clientScope = "ConfigMS";
-		}else if (parameters.getPolicyName().contains("Config_BRMS_Raw")){
-			clientScope = "ConfigBrmsRaw";
-		} else if (parameters.getPolicyName().contains("Config_BRMS_Param")){
-			clientScope = "ConfigBrmsParam";
-		} else {
-			clientScope = "Config";
-		}
-		
-		logger.debug("clientScope is " + clientScope);
-		
-		if (clientScope==null||clientScope.equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + parameters.getPolicyName() + " is not a valid Policy Name.");
-			return XACMLErrorConstants.ERROR_DATA_ISSUE + parameters.getPolicyName() + " is not a valid Policy Name.";
-		}
-		
-		if (parameters.getPolicyName()==null||parameters.getPolicyName().equalsIgnoreCase("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
-		} else if (parameters.getPdpGroup()==null||parameters.getPdpGroup().equals("")){
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No PDP Group given.");
-			response = XACMLErrorConstants.ERROR_DATA_ISSUE + "No PDP Group given.";
-		} else {
-			
-			//send JSON object to PAP
-			try {
-				response = (String) callPAP(null, new String[] {"policyName="+parameters.getPolicyName(), "groupId="+pdpGroup, "apiflag=deletePdpApi", "operation=delete" }, parameters.getRequestID(), clientScope);
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}		
-			
-		}
-		
-		return response;
+	public String createUpdateConfigPolicy(String policyName, String policyDescription, String ecompName, String configName,
+			Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
+		return createUpdateConfigPolicyImpl(policyName, policyDescription, ecompName, configName,
+				configAttributes, configType, body, policyScope, requestID,
+				riskLevel, riskType, guard, ttlDate, updateFlag);
 	}
 	
 	/*
-	 * Copy a single Policy file from the input stream to the PAP Servlet.
-	 * Either this works (silently) or it throws an exception.
-	 * 
+	 * Create Config Policy API Implementation
 	 */
-	public String copyFile(String policyId, String group, StdPAPPolicy location, String clientScope, UUID requestID) throws PAPException {
-		String response = null;
-		//String clientScope = null;
-		
-		// send the policy file to the PAP Servlet
+	public String createUpdateConfigPolicyImpl(String policyName, String policyDescription, String ecompName, String configName,
+			Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
+		PolicyParameters policyParameters = new PolicyParameters();
+		policyParameters.setPolicyClass(PolicyClass.Config);
+		policyParameters.setPolicyConfigType(PolicyConfigType.Base);
+		if(policyScope==null|| policyScope.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
+		}
+		if(policyName==null|| policyName.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
+		}
+		policyParameters.setPolicyName(policyScope+"."+policyName);
+		policyParameters.setPolicyDescription(policyDescription);
+		policyParameters.setEcompName(ecompName);
+		policyParameters.setConfigName(configName);
+		Map<AttributeType, Map<String, String>> attributes = new HashMap<AttributeType, Map<String, String>>();
+		attributes.put(AttributeType.MATCHING, configAttributes);
+		policyParameters.setAttributes(attributes);
+		policyParameters.setConfigBodyType(PolicyType.valueOf(configType));
+		policyParameters.setConfigBody(body);
+		policyParameters.setRequestID(requestID);
+		policyParameters.setRiskLevel(riskLevel);
+		policyParameters.setRiskType(riskType);
+		policyParameters.setGuard(Boolean.parseBoolean(guard));
 		try {
-			response = (String) callPAP(location, new String[] {"groupId=" + group, "policyId="+policyId, "apiflag=api", "operation=post"}, requestID, clientScope);
-		} catch (Exception e) {
-			String message = "Unable to PUT policy '" + policyId + "', e:" + e;
-			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + message, e);
-			throw new PAPException(message);
+			policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
+		} catch (ParseException e) {
+			LOGGER.warn("Error Parsing date given " + ttlDate);
+			policyParameters.setTtlDate(null);
 		}
-		
-		return response;
+		return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
 	}
 	
-	public String copyPolicy(PDPPolicy policy, String group, String policyType, UUID requestID) throws PAPException {
-		String response = null;
-		
-		if (policy == null || group == null) {
-			throw new PAPException("Null input policy="+policy+"  group="+group);
+	public String createUpdateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
+		return createUpdateConfigFirewallPolicyImpl(policyName, firewallJson, policyScope, requestID,
+				riskLevel, riskType, guard, ttlDate, updateFlag);
+	}
+	
+	/*
+	 * Create Update Config Firewall Policy API implementation
+	 */
+	public String createUpdateConfigFirewallPolicyImpl(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
+			String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
+		PolicyParameters policyParameters = new PolicyParameters();
+		policyParameters.setPolicyClass(PolicyClass.Config);
+		policyParameters.setPolicyConfigType(PolicyConfigType.Firewall);
+		if(policyScope==null|| policyScope.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
 		}
+		if(policyName==null|| policyName.trim().isEmpty()){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
+			LOGGER.error(message);
+			throw new PolicyException(message);
+		}
+		policyParameters.setPolicyName(policyScope+"."+policyName);
+		policyParameters.setConfigBody(firewallJson.toString());
+		policyParameters.setRequestID(requestID);
+		policyParameters.setRiskLevel(riskLevel);
+		policyParameters.setRiskType(riskType);
+		policyParameters.setGuard(Boolean.parseBoolean(guard));
 		try {
-			StdPAPPolicy location = new StdPAPPolicy(policy.getLocation());
-			response = copyFile(policy.getId(), group, location, policyType, requestID);
-		} catch (Exception e) {
-			String message = "Unable to PUT policy '" + policy.getId() + "', e:" + e;
-			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + message, e);
-			throw new PAPException(message);
+			policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
+		} catch (NullPointerException | ParseException e) {
+			LOGGER.warn("Error Parsing date given " + ttlDate);
+			policyParameters.setTtlDate(null);
 		}
-		
-		return response;
-	}
-
-	public Object callPAP(Object content, String[] parameters, UUID requestID, String clientScope) throws Exception {
-		String response = null;
-		HttpURLConnection connection = null;
-		String requestMethod = null;
-		String operation = null;
-		responseCode = 0; 
-		// Checking for the available PDPs is done during the first Request and the List is going to have the connected PDP as first element.
-		// This makes it Real-Time to change the list depending on their availability.
-		if (paps == null || paps.isEmpty()) {
-		logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PAPs List is Empty.");
-		throw new Exception(XACMLErrorConstants.ERROR_DATA_ISSUE +"PAPs List is empty.");
-		}else {
-			int papsCount = 0;
-			boolean connected = false;
-			while (papsCount < paps.size()) {
-				try {
-					String fullURL = paps.get(0);
-					if (parameters != null && parameters.length > 0) {
-						String queryString = "";
-						for (String p : parameters) {
-							queryString += "&" + p;
-							if (p.equalsIgnoreCase("operation=post")){
-								requestMethod = "POST";
-							} else if (p.equalsIgnoreCase("operation=delete")){
-								requestMethod = "DELETE";
-								operation = "delete";
-							} else {
-								requestMethod = "PUT";
-								if (p.equalsIgnoreCase("operation=create")){
-									operation = "create";
-								} else if (p.equalsIgnoreCase("operation=update")){
-									operation = "update";
-								} else if (p.equalsIgnoreCase("operation=createDictionary")){
-									operation = "createDictionary";
-								}
-							}
-						}
-						fullURL += "?" + queryString.substring(1);
-					}
-	
-					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 "
-							+ encodingPAP.get(0));
-					
-					connection.setRequestProperty("Environment", environment);
-					connection.setRequestProperty("ClientScope", clientScope);
-					
-					//set the method and headers
-					connection.setRequestMethod(requestMethod);
-					connection.setUseCaches(false);
-					connection.setInstanceFollowRedirects(false);
-					connection.setDoOutput(true);
-					connection.setDoInput(true);
-					// Adding RequestID
-					if (requestID == null) {
-						requestID = UUID.randomUUID();
-						logger.info("No request ID provided, sending generated ID: " + requestID.toString());
-					} else {
-						logger.info("Using provided request ID: " + requestID.toString());
-					}
-					connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
-
-					if (content != null) {
-						if (content instanceof InputStream) {
-							try {
-								//send  current configuration
-								try (OutputStream os = connection.getOutputStream()) {
-									int count = IOUtils.copy((InputStream)content, os);
-									if (logger.isDebugEnabled()) {
-										logger.debug("copied to output, bytes=" + count);
-									}
-								}
-							} catch (Exception e) {
-								logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to write content in 'PUT'", e);
-								throw e;
-							}
-						} else {
-							// the content is an object to be encoded in JSON
-							ObjectMapper mapper = new ObjectMapper();
-							if(!junit){
-								mapper.writeValue(connection.getOutputStream(), content);
-							}
-						}
-					}
-	
-					//DO the connect
-					connection.connect();
-					responseCode = connection.getResponseCode();
-					// If Connected to PAP then break from the loop and continue with the Request 
-					if (connection.getResponseCode() > 0 || junit) {
-						connected = true;
-						break;
-
-					} else {
-						logger.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error");
-					}
-				} catch (Exception e) {
-					// This means that the PAP is not working 
-					if (junit) {
-						connected = true;
-						break;
-					}
-					logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e);
-				}
-				papsCount++;
-			}
-	
-			if (connected) {
-				//Read the Response
-				logger.debug("connected to the PAP : " + paps.get(0));
-				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 (responseCode == 200 || junit) {
-						
-						// Check for successful creation of policy
-						String isSuccess = null;
-						if(!junit){ //is this a junit test?
-							isSuccess = connection.getHeaderField("successMapKey");
-							operation = connection.getHeaderField("operation");
-						} else {
-							isSuccess = "success";
-						}
-						
-						if (isSuccess.equals("success")) {
-							if (operation.equals("update")) {
-								logger.info("Transaction ID: " + requestID + " --Policy Updated Successfully!" );
-								response = "Transaction ID: " + requestID + " --Policy with the name " + connection.getHeaderField("policyName") + " was successfully updated.";
-							} else if (operation.equals("delete")) {
-								logger.info("Transaction ID: " + requestID + " --Policy Deleted Successfully!");
-								response = "Transaction ID: " + requestID + " --The policy was successfully deleted.";    
-							} else if (operation.equals("import")) {
-								logger.info("Transaction ID: " + requestID + " --Policy Engine Import Successful!");
-								response = "Transaction ID: " + requestID + " --The policy engine import for " + connection.getHeaderField("service") +  " was successfull.";    
-							}else {
-								logger.info("Transaction ID: " + requestID + " --Policy Created Successfully!" );
-								response = "Transaction ID: " + requestID + " --Policy with the name " + connection.getHeaderField("policyName") + " was successfully created.";
-							}
-									
-						} else {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to Create/Update the Policy!");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Unable to Create/Update the Policy!";
-						}
-					} else if (connection.getResponseCode() == 202) {
-						if (connection.getHeaderField("operation")!=null && connection.getHeaderField("operation").equalsIgnoreCase("delete")){
-							if (connection.getHeaderField("lockdown")!=null && connection.getHeaderField("lockdown").equals("true")){
-								logger.warn("Transaction ID: " + requestID + "Policies are locked down.");
-								response = "Transaction ID: " + requestID + " --Policies are locked down, please try again later.";
-							}
-						}
-					} else if (connection.getResponseCode() == 204) {
-						if (connection.getHeaderField("operation")!=null && connection.getHeaderField("operation").equals("push")){
-							logger.info("Transaction ID: " + requestID + " --Policy '" + connection.getHeaderField("policyId") +
-									"' was successfully pushed to the PDP group '" + connection.getHeaderField("groupId") + "'.");
-							response = "Transaction ID: " + requestID + " --Policy '" + connection.getHeaderField("policyId") +
-									"' was successfully pushed to the PDP group '" + connection.getHeaderField("groupId") + "'.";
-						}
-					} else if (connection.getResponseCode() == 400 && connection.getHeaderField("error")!=null){
-						if (connection.getHeaderField("error").equals("noPolicyExist")) {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
-						} else if (connection.getHeaderField("error").equals("invalidPolicyName")) {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
-        				+ "policyName must be the full name of the file to be deleted including version and extension");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
-			        				+ "policyName must be the full name of the file to be deleted including version and extension";
-						} else if (connection.getHeaderField("error").equals("actionPolicyDB")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not find " + connection.getHeaderField("actionAttribute") + " in the ActionPolicyDict table.");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid actionAttribute given.";
-						} else if (connection.getHeaderField("error").equals("serviceModelDB")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Service or Version.  The Service Model, " 
-									+ connection.getHeaderField("modelName") + " of version " + connection.getHeaderField("modelVersion") 
-									+ " was not found in the dictionary.");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Service or Version.  The Service Model, " 
-									+ connection.getHeaderField("modelName") + " of version " + connection.getHeaderField("modelVersion") 
-									+ " was not found in the dictionary.";
-						} else if (connection.getHeaderField("error").equals("FWDBError")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error when inserting Firewall ConfigBody data into database.");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Error when inserting Firewall ConfigBody data into the database.";
-						} else if (connection.getHeaderField("error").equals("savePolicy")){
-							logger.error(connection.getHeaderField("message"));
-							response = connection.getHeaderField("message");
-						}
-					} 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. ");
-						response = 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. ";	
-					} else if (connection.getResponseCode() == 404 && connection.getHeaderField("error")!=null) {
-						if (connection.getHeaderField("error").equals("unknownGroupId")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + connection.getHeaderField("message"));
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + connection.getHeaderField("message") +  
-									" Please check the pdpGroup you are requesting to move the policy to.";
-						}
-					} else if (connection.getResponseCode() == 409 && connection.getHeaderField("error")!=null) {
-						if (connection.getHeaderField("error").equals("modelExistsDB")) {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Import Value Exist Error");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Import Value Exist Error:  The import value "+connection.getHeaderField("service")+" already exist on the PAP. "
-									+ "Please create a new import value.";
-						}else if (connection.getHeaderField("error").equals("policyExists")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy Exist Error");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy Exist Error:  The Policy "+connection.getHeaderField("policyName")+" already exist on the PAP. "
-									+ "Please create a new policy or use the update API to modify the existing one.";
-						}
-					} else if (connection.getResponseCode() == 500 && connection.getHeaderField("error")!=null) {
-						if (connection.getHeaderField("error").equals("jpautils")){
-							logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Could not create JPAUtils instance on the PAP");
-							response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Could not create JPAUtils instance on the PAP";
-						} else if (connection.getHeaderField("error").equals("deleteDB")){
-							logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to delete Policy from database.");
-							response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed to delete Policy from database.";
-						} else if (connection.getHeaderField("error").equals("deleteFile")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot delete the policy file.");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot delete the policy file";
-						} else if (connection.getHeaderField("error").equals("groupUpdate")){
-							logger.error(connection.getHeaderField("message"));
-							response = connection.getHeaderField("message");
-						}else if (connection.getHeaderField("error").equals("unknown")){
-							logger.error(XACMLErrorConstants.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
-							response = XACMLErrorConstants.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.";
-						} else if (connection.getHeaderField("error").equals("deleteConfig")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot delete the configuration or action body file in specified location");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot delete the configuration or action body file in specified location.";
-						}else if (connection.getHeaderField("error").equals("missing")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to create value in database because service does match a value in file");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to create value in database because service does match a value in file";
-						}else if (connection.getHeaderField("error").equals("importDB")){
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Database errors during policy engine import");
-							response = XACMLErrorConstants.ERROR_DATA_ISSUE + "Database errors during policy engine import";
-						}else if (connection.getHeaderField("error").equals("policyCopyError")){
-							logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + connection.getHeaderField("message"));
-							response = XACMLErrorConstants.ERROR_PROCESS_FLOW + connection.getHeaderField("message");
-						}else if (connection.getHeaderField("error").equals("addGroupError")){
-							logger.error(connection.getHeaderField("message"));
-							response = connection.getHeaderField("message");
-						}else if (connection.getHeaderField("error").equals("error")){
-							logger.error(XACMLErrorConstants.ERROR_UNKNOWN + "Could not create or update the policy for and unknown reason");
-							response = XACMLErrorConstants.ERROR_UNKNOWN + "Could not create or update the policy for and unknown reason";
-						}
-					} else {
-						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST:  Error occured while attempting perform this operation.. the request may be incorrect.");
-						response = XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST:  Error occured while attempting perform this operation.. the request may be incorrect.";
-					}
-				} catch (IOException e) {
-					logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
-					response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + e;
-					throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"ERROR in connecting to the PAP ", e);
-				} 
-				
-				if (junit){
-					response = "success";
-				}
-				return response;
-	
-			} else {
-				response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps;
-				return response;
-			}	
-		}
-	
+		return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
 	}
 	
-	// change getSelectedURI method to receive requestID to be used to send to PAP on the GET request so PAP won't generate another
-	// private URI getSelectedURI(String gitPath, String clientScope){
-	private URI getSelectedURI(String gitPath, String clientScope, UUID requestID){
-		//Connect to the PAP
-		URI selectedURI = null;
-		HttpURLConnection connection = null;
-		String [] parameters = {"apiflag=uri", "gitPath="+gitPath};
-
-
-		// Checking for the available PDPs is done during the first Request and the List is going to have the connected PDP as first element.
-		// This makes it Real-Time to change the list depending on their availability.
-		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());
+	public void setClientKey(String clientKey){
+		if(clientKey!=null && !clientKey.isEmpty()){
+			StdPolicyEngine.pass = clientKey;
+			setClientEncoding();
 		}
-		}else {
-			int papsCount = 0;
-			boolean connected = false;
-			while (papsCount < paps.size()) {
-				try {
-					String fullURL = paps.get(0);
-					if (parameters != null && parameters.length > 0) {
-						String queryString = "";
-						for (String p : parameters) {
-							queryString += "&" + p;
-						}
-						fullURL += "?" + queryString.substring(1);
-					}
-	
-					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 "
-							+ encodingPAP.get(0));
-					
-					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);
-
-					// set requestID in header properties to be used to send to PAP on the GET request so PAP won't generate another
-					connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
-	
-					//DO the connect
-					connection.connect();
-					responseCode = connection.getResponseCode();
-					// 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);
-				}
-				papsCount++;
-			}
-	
-			if (connected) {
-				//Read the Response
-				logger.debug("connected to the PAP : " + paps.get(0));
-				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
-						String uri = connection.getHeaderField("selectedURI");
-						logger.debug("URI from Header: " + uri);
-						if (uri != null && !uri.equalsIgnoreCase("")) {
-							selectedURI = URI.create(uri);
-							return selectedURI;
-						} else {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "could not retrieve the gitPath from the PAP");
-						}
-					} else if (connection.getResponseCode() == 404) {
-						logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "response code of the URL is " 
-									+ connection.getResponseCode() + ". This indicates a problem with getting the gitPath from the PAP");
-					} else {
-						logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "BAD REQUEST:  Error occured while getting the gitPath 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());
-					}
-				} 
-	
-			} 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());
-				}
-			}	
-		}
-		return selectedURI;
-						
 	}
-	
-	// Make a call to the PAP to get the gitPath
-	// change getGitPath method to receive requestID to be used to send to PAP on the GET request so PAP won't generate another
-	// private String getGitPath(String policyScope, String filePrefix, String policyName, String activeVersion, String clientScope){
-	private String getGitPath(String policyScope, String filePrefix, String policyName, String activeVersion, String clientScope, UUID requestID){
-
-		//Connect to the PAP
-		String gitPath = null;
-		HttpURLConnection connection = null;
-		String [] parameters = {"apiflag=gitPath", "policyScope="+policyScope, "filePrefix="+filePrefix, 
-									"policyName="+policyName, "activeVersion="+activeVersion};
-		
-
-		// Checking for the available PDPs is done during the first Request and the List is going to have the connected PDP as first element.
-		// This makes it Real-Time to change the list depending on their availability.
-		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());
-		}
-		}else {
-			int papsCount = 0;
-			boolean connected = false;
-			while (papsCount < paps.size()) {
-				try {
-					String fullURL = paps.get(0);
-					if (parameters != null && parameters.length > 0) {
-						String queryString = "";
-						for (String p : parameters) {
-							queryString += "&" + p;
-						}
-						fullURL += "?" + queryString.substring(1);
-					}
-	
-					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 "
-							+ encodingPAP.get(0));
-					
-					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);
-
-					// set requestID in header properties to be used to send to PAP on the GET request so PAP won't generate another
-					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);
-				}
-				papsCount++;
-			}
-	
-			if (connected) {
-				//Read the Response
-				logger.debug("connected to the PAP : " + paps.get(0));
-				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
-						gitPath = connection.getHeaderField("gitPath");
-						this.policyId = connection.getHeaderField("policyId");
-						this.description = connection.getHeaderField("description");
-						this.pushVersion = connection.getHeaderField("version");
-						String isValid = connection.getHeaderField("isValid");
-						this.isValid = Boolean.parseBoolean(isValid);
-						
-						logger.debug("GitPath from Header: " + gitPath);
-						logger.debug("policyId from Header: " + policyId);
-						logger.debug("description from Header: " + description);
-						logger.debug("version from Header: " + pushVersion);
-						logger.debug("isValid from Header: " + isValid);
-						
-						if (gitPath != null && !gitPath.equalsIgnoreCase("")) {
-							return gitPath;
-						} else {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "could not retrieve the gitPath from the PAP");
-						}
-					} else if (connection.getResponseCode() == 404) {
-						logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "response code of the URL is " 
-									+ connection.getResponseCode() + ". This indicates a problem with getting the gitPath from the PAP");
-					} else {
-						logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "BAD REQUEST:  Error occured while getting the gitPath 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());
-					}
-				} 
-	
-			} 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());
-				}
-			}	
-		}
-		return gitPath;
-						
-	}
-
-	// change getActiveVersion method to receive requestID to be used to send to PAP on the GET request so PAP won't generate another
-//	private String getActiveVersion(String policyScope, String filePrefix, String policyName, String clientScope) {
-	private String getActiveVersion(String policyScope, String filePrefix, String policyName, String clientScope, UUID requestID) {		
-
-		//Connect to the PAP
-		String version = null;
-		HttpURLConnection connection = null;
-		String [] parameters = {"apiflag=version","policyScope="+policyScope, "filePrefix="+filePrefix, "policyName="+policyName};
-		
-
-		// Checking for the available PDPs is done during the first Request and the List is going to have the connected PDP as first element.
-		// This makes it Real-Time to change the list depending on their availability.
-		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());
-		}
-		}else {
-			int papsCount = 0;
-			boolean connected = false;
-			while (papsCount < paps.size()) {
-				try {
-					String fullURL = paps.get(0);
-					if (parameters != null && parameters.length > 0) {
-						String queryString = "";
-						for (String p : parameters) {
-							queryString += "&" + p;
-						}
-						fullURL += "?" + queryString.substring(1);
-					}
-	
-					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 "
-							+ encodingPAP.get(0));
-					
-					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);
-
-					// set requestID in header properties to be used to send to PAP on the GET request so PAP won't generate another
-					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);
-				}
-				papsCount++;
-			}
-	
-			if (connected) {
-				//Read the Response
-				logger.debug("connected to the PAP : " + paps.get(0));
-				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());
-					}
-				} 
-	
-			} 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());
-				}
-			}	
-		}
-		return version;
-	}
-	
-	// Validation for json inputs
-	public static boolean isJSONValid(String data) {
-		try {
-			new JSONObject(data);
-			InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-			JsonReader jsonReader = Json.createReader(stream);
-			logger.debug("Json Value is: " + jsonReader.read().toString() );
-		} catch (Exception e) {
-			return false;
-		}
-		return true;
-	}
-	
+	/*
+	 * Get the Environment. 
+	 */
+	public static String getEnvironment() {
+		return environment;
+	} 
 	/*
 	 * Rotate the PDP list upon WEBsocket Failures
 	 */
-	public static void rotateList() {
+	public static void rotatePDPList() {
 		Collections.rotate(pdps, -1);
 		Collections.rotate(encoding, -1);
-		/* not required for 1510. //TODO uncomment when PAP API has been implemented
-		 * This Broke the PyPDP :( Since there is no PAP LIST yet. 
-		Collections.rotate(paps,  -1);
-		Collections.rotate(encodingPAP, -1);
-		*/
 	}
-
 	/*
 	 * Get the latest PDP
 	 */
 	public static String getPDPURL() {
 		return pdps.get(0);
 	}
-	
-	/*
-	 * Get the latest PAP
-	 */
-	public static String getPAPURL() {
-		return paps.get(0);
-	}
-	
-	private JsonObject stringToJsonObject(String value) throws Exception{
-		JsonReader jsonReader = Json.createReader(new StringReader(value));
-		JsonObject object = jsonReader.readObject();
-		jsonReader.close();
-		return object;
-	}
-	
-	private String getJsonResponseString() {
-		String jsonString = "{\"Response\":[{\"Status\":{\"StatusCode\":{\"Value\":\"urn:oasis:names:tc:xacml:1.0:status:ok\"}},"
-				+ "\"AssociatedAdvice\":[{\"AttributeAssignment\":[{\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\","
-				+ "\"Issuer\":\"\",\"AttributeId\":\"type\",\"Value\":\"Configuration\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},"
-				+ "{\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"URLID\",\"Value\":"
-				+ "\"$URL/Config/JunitTest.Config_testing.1.json\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#anyURI\"},{\"Category\":"
-				+ "\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"PolicyName\",\"Value\":"
-				+ "\"JunitTest.Config_testing.1.xml\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Category\":"
-				+ "\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"VersionNumber\",\"Value\":"
-				+ "\"1\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\","
-				+ "\"Issuer\":\"\",\"AttributeId\":\"matching:ECOMPName\",\"Value\":\"test\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},"
-				+ "{\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"matching:ConfigName\","
-				+ "\"Value\":\"TestName\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Category\":"
-				+ "\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"matching:service\","
-				+ "\"Value\":\"ControllerServiceOpendcaeCapsuleServiceInstance\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},"
-				+ "{\"Category\":\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"matching:uuid\","
-				+ "\"Value\":\"TestUUID\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Category\":"
-				+ "\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"matching:Location\","
-				+ "\"Value\":\"Edge\",\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Category\":"
-				+ "\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\",\"Issuer\":\"\",\"AttributeId\":\"Priority\",\"Value\":\"1\",\"DataType\":"
-				+ "\"http://www.w3.org/2001/XMLSchema#string\"}],\"Id\":\"MSID\"}],\"Decision\":\"Permit\"}]}";
-		
-		return jsonString;
-	}
-	
-	public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws Exception {
-		return policyEngineImport(importParameters, userName,  pass);
-	}
-	
-	public PolicyChangeResponse policyEngineImport(ImportParameters importParameters, String userID, String passcode) throws Exception {
-		StdPolicyChangeResponse response = new StdPolicyChangeResponse();
-		String resource= "policyEngineImport";
-		if(!checkPermissions(userID, passcode, resource)){
-			logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseMessage(XACMLErrorConstants.ERROR_PERMISSIONS + "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to:" + resource);
-			response.setResponseCode(401);
-			return response;
-		}
-		InputStream targetStream = null;
-		if(importParameters.getServiceName()!=null && importParameters.getVersion()!=null && importParameters.getServiceType()!=null){
-			// This is Config Class Policy. 
-			if(importParameters.getFilePath()!=null){
-				File input = new File(importParameters.getFilePath());
-				if (input.getName().endsWith(".xmi") ||  input.getName().endsWith(".zip")){
-				    try {
-				    	if (input.exists()){
-				    		targetStream = new FileInputStream(input);
-				    	}else {
-							logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "File provided in ImportParameters does not exists.");
-							response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "File provided in ImportParameters does not exist.");		
-							return response;
-				    	}
-					} catch (Exception e) {
-						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error reading in File");
-						response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error in reading in the file provided");
-					}	
-				}else{
-					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect File Data type.");
-					response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "Incorrect File Type Given. Please use a file of type .xmi or .zip.");		
-					return response;
-				}
-				String[] parameters = new String[] {"importService=" + importParameters.getServiceType(), "serviceName=" 
-						+ importParameters.getServiceName(), "fileName=" + input.getName(), "version=" + importParameters.getVersion()};
-				String responseMessage =  (String) callPAP(targetStream, parameters, importParameters.getRequestID(), "importMS");
-				response.setResponseMessage(responseMessage);
-			}else{
-				logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing required ImportParameters value.");
-				response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing required ImportParameters value.");		
-			}
-		}else{
-			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing required ImportParameters value.");
-			response.setResponseMessage(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing required ImportParameters value.");		
-		}	
-		return response;
-	}
-	
-	/*
-	 * Give userID, Passcode and the Resoruce they are requesting for. 
-	 */
-	private boolean checkPermissions(String userID, String passcode, String resource){
-		Boolean result = false;
-		if(pyPDPClientFile!=null){
-			// Backward compatible pyPDP called us. So validate the user names and scope.
-			Path clientPath = Paths.get(pyPDPClientFile);
-			if (Files.notExists(clientPath)) {
-				result = false;
-			}else if(clientPath.toString().endsWith(".properties")) {
-				try {
-					HashMap<String, ArrayList<String>> clientMap = readProps(clientPath);
-					if (clientMap.containsKey(userID) && clientMap.get(userID).get(0).equals(passcode)) {
-						result= true;
-					}
-				} catch (Exception e) {
-					result = false;
-				}
-			}
-		}else{
-			//Allowing Every Client who ever don't have access for AAF and Backup Client file
-			result = true;
-		}
-		return result;
-	}
-	
-	private HashMap<String, ArrayList<String>> readProps(Path clientPath) throws Exception{
-		InputStream in;
-		Properties clientProp = new Properties();
-		try {
-			in = new FileInputStream(clientPath.toFile());
-			clientProp.load(in);
-		} catch (IOException e) {
-			logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
-			throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Cannot Load the Properties file", e);
-		}
-		// Read the Properties and Load the Clients and their scopes.
-		HashMap<String, ArrayList<String>>clientMap = new HashMap<String, ArrayList<String>>();
-		// 
-		for (Object propKey : clientProp.keySet()) {
-			String clientID = (String)propKey; 
-			String clientValue = clientProp.getProperty(clientID);
-			if (clientValue != null) {
-				if (clientValue.contains(",")) {
-					ArrayList<String> clientValues = new ArrayList<String>(Arrays.asList(clientValue.split("\\s*,\\s*")));
-					if(clientValues.get(0)!=null || clientValues.get(1)!=null || clientValues.get(0).isEmpty() || clientValues.get(1).isEmpty()){
-						clientMap.put(clientID, clientValues);
-					}
-				} 
-			}
-		}
-		if (clientMap == null || clientMap.isEmpty()) {
-			logger.debug(XACMLErrorConstants.ERROR_PERMISSIONS + "No Clients ID , Client Key and Scopes are available. Cannot serve any Clients !!");
-			throw new Exception("Empty Client file");
-		}
-		return clientMap;
-	}
-	
-	protected boolean isNumeric(String str)
-	{
-		for (char c : str.toCharArray())
-		{
-			if (!Character.isDigit(c)) return false;
-		}
-		return true;
-	} 
-	
-	private String ConvertDate(Date date){
-		String strDate = null;
-		if (date!=null)
-		{
-			SimpleDateFormat dateformatJava = new SimpleDateFormat("dd-MM-yyyy");
-			strDate = dateformatJava.format(date);
-		}
-		
-		return strDate;
-	}
-}
+}
\ No newline at end of file
diff --git a/PolicyEngineAPI/src/main/resources/logback.xml b/PolicyEngineAPI/src/main/resources/logback.xml
index dd36a50..9e990cc 100644
--- a/PolicyEngineAPI/src/main/resources/logback.xml
+++ b/PolicyEngineAPI/src/main/resources/logback.xml
@@ -44,14 +44,15 @@
            <property name="defaultAuditPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
            <property name="defaultAuditPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{ElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
    -->
-   <property name="defaultAuditPattern" value="%X{TransactionBeginTimestamp}|%X{TransactionEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{TransactionElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+   <property name="defaultAuditPattern" value="%X{TransactionBeginTimestamp}|%X{TransactionEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{statusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{instanceUuid}|%p|%X{severity}|%X{serverIpAddress}|%X{TransactionElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
   
   
   
    <!--    M E T R I C 
           <property name="defaultMetricPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
    -->
-   <property name="defaultMetricPattern" value="%X{MetricBeginTimestamp}|%X{MetricEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%p|%X{severity}|%X{serverIpAddress}|%X{MetricElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+   <property name="defaultMetricPattern" value="%X{MetricBeginTimestamp}|%X{MetricEndTimestamp}|%X{requestId}|%X{serviceInstanceId}|%t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{targetEntity}|%X{targetServiceName}|%X{statusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%p|%X{severity}|%X{serverIpAddress}|%X{MetricElapsedTime}|%X{server}|%X{clientIpAddress}|%c||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%msg%n" />
+  
   
      
    
