diff --git a/ECOMP-PAP-REST/src/main/java/hibernate.cfg.xml b/ECOMP-PAP-REST/src/main/java/hibernate.cfg.xml
new file mode 100644
index 0000000..33f5177
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/hibernate.cfg.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP-PAP-REST
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+
+
+<!DOCTYPE hibernate-configuration SYSTEM
+    "classpath://org/hibernate/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+	<session-factory>
+		
+		<!-- Hibernate JPA Mapping Classes -->
+		<mapping class="org.openecomp.policy.rest.jpa.Attribute"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ActionPolicyDict"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ActionList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.AddressGroup"/>
+		<mapping class="org.openecomp.policy.rest.jpa.BRMSParamTemplate"/>
+		<mapping class="org.openecomp.policy.rest.jpa.Category"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ClosedLoopD2Services"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ClosedLoopSite"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ConstraintType"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ConstraintValue"/>
+		<mapping class="org.openecomp.policy.rest.jpa.Datatype"/>	
+		<mapping class="org.openecomp.policy.rest.jpa.DCAEuuid"/>
+		<mapping class="org.openecomp.policy.rest.jpa.DecisionSettings"/>	
+		<mapping class="org.openecomp.policy.rest.jpa.DescriptiveScope"/>
+		<mapping class="org.openecomp.policy.rest.jpa.EcompName"/>
+		<mapping class="org.openecomp.policy.rest.jpa.EnforcingType"/>
+		<mapping class="org.openecomp.policy.rest.jpa.FirewallDictionaryList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.FunctionDefinition"/>
+		<mapping class="org.openecomp.policy.rest.jpa.FunctionArgument"/>
+		<mapping class="org.openecomp.policy.rest.jpa.GroupPolicyScopeList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.GroupServiceList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.MicroServiceConfigName"/>
+		<mapping class="org.openecomp.policy.rest.jpa.MicroServiceLocation"/>
+		<mapping class="org.openecomp.policy.rest.jpa.MicroServiceModels"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PEPOptions"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PolicyScopeClosedLoop"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PolicyScopeResource"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PolicyScopeType"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PolicyScopeService"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PortList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.PREFIXLIST"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ProtocolList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.ServiceList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.SecurityZone"/>
+		<mapping class="org.openecomp.policy.rest.jpa.TermList"/>
+		<mapping class="org.openecomp.policy.rest.jpa.UserInfo"/>
+		<mapping class="org.openecomp.policy.rest.jpa.VarbindDictionary"/>
+		<mapping class="org.openecomp.policy.rest.jpa.VNFType"/>
+		<mapping class="org.openecomp.policy.rest.jpa.VSCLAction"/>
+		<mapping class="org.openecomp.policy.rest.jpa.Zone"/>
+		<mapping class="org.openecomp.policy.rest.jpa.RiskType"/>
+		<mapping class="org.openecomp.policy.rest.jpa.SafePolicyWarning"/>
+	</session-factory>
+</hibernate-configuration>
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/HibernateSession.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/HibernateSession.java
new file mode 100644
index 0000000..17babfa
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/HibernateSession.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+
+
+public class HibernateSession{
+	private static SessionFactory xacmlsessionFactory;
+
+
+	static {
+		try {
+			Configuration configuration= new Configuration();
+			configuration.setProperty("hibernate.connection.url", XACMLPapServlet.papDbUrl);
+			configuration.setProperty("hibernate.connection.username", XACMLPapServlet.papDbUser);
+			configuration.setProperty("hibernate.connection.password", XACMLPapServlet.papDbPassword);
+			configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
+			configuration.setProperty("hibernate.connection.driver_class", XACMLPapServlet.papDbDriver);	
+			configuration.setProperty("hibernate.show_sql", "false");	
+			configuration.setProperty("hibernate.connection.autocommit", "true");
+			configuration.setProperty("hibernate.c3p0.min_size", "5");
+			configuration.setProperty("hibernate.c3p0.max_size", "200");
+			configuration.setProperty("hibernate.c3p0.timeout", "3600");
+			configuration.setProperty("hibernate.c3p0.idle_test_period", "3600");
+			
+			StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
+			xacmlsessionFactory = configuration.configure("/hibernate.cfg.xml").buildSessionFactory(builder.build());
+			
+		} catch (Throwable ex) {
+			throw new ExceptionInInitializerError(ex);
+		}
+	}
+	public static Session getSessionFactory() throws HibernateException {
+		return xacmlsessionFactory.openSession();
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/WebConfig.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/WebConfig.java
new file mode 100644
index 0000000..b84049c
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/WebConfig.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Base64;
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRegistration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+
+public class WebConfig implements WebApplicationInitializer {
+	
+	private static final Log logger	= LogFactory.getLog(WebConfig.class);
+	
+	@Override
+	public void onStartup(ServletContext container) {
+		
+		//need to get properties for userid and password on the pap to get authorization string used in URI Mapping
+		Properties prop = new Properties();
+		String propFileName = "xacml.pap.properties";
+		
+		try {
+			InputStream is = new FileInputStream(propFileName);
+			prop.load(is);
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "property file '" + propFileName + "' not found in the classpath");
+		}
+		
+		String papID = prop.getProperty("xacml.rest.pap.userid");
+		String papPass = prop.getProperty("xacml.rest.pap.password");
+		
+		String usernameAndPassword = papID+":"+papPass;		
+		String authorizationString = Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());
+		
+		
+		XmlWebApplicationContext appContext = new XmlWebApplicationContext();
+		appContext.setConfigLocation("classpath:spring.xml");
+		
+		System.out.println("Spring XML File Location: " + appContext.getConfigLocations());
+		logger.info("Spring XML File Location: " + appContext.getConfigLocations());
+
+		ServletRegistration.Dynamic dispatcher =
+				container.addServlet("dispatcher", new DispatcherServlet(appContext));
+		dispatcher.setLoadOnStartup(1);
+		dispatcher.addMapping("/@Auth@"+authorizationString+"/ecomp/*");
+	}
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/XACMLPapServlet.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/XACMLPapServlet.java
new file mode 100644
index 0000000..efc7070
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/XACMLPapServlet.java
@@ -0,0 +1,4858 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+import javax.persistence.EntityManagerFactory;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.pap.xacml.rest.components.ActionPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.AutoPushPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.ClosedLoopPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.ConfigPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.CreateBrmsParamPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.CreateBrmsRawPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.CreateClosedLoopPerformanceMetrics;
+import org.openecomp.policy.pap.xacml.rest.components.CreateNewMicroSerivceModel;
+import org.openecomp.policy.pap.xacml.rest.components.DecisionPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.FirewallConfigPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.MicroServiceConfigPolicy;
+import org.openecomp.policy.pap.xacml.rest.components.Policy;
+import org.openecomp.policy.pap.xacml.rest.components.PolicyDBDao;
+import org.openecomp.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
+import org.openecomp.policy.pap.xacml.rest.model.RemoveGroupPolicy;
+import org.openecomp.policy.pap.xacml.rest.util.JPAUtils;
+import org.openecomp.policy.pap.xacml.restAuth.CheckPDP;
+import org.openecomp.policy.rest.XACMLRest;
+import org.openecomp.policy.rest.XACMLRestProperties;
+import org.openecomp.policy.rest.jpa.ActionPolicyDict;
+import org.openecomp.policy.rest.jpa.BRMSParamTemplate;
+import org.openecomp.policy.rest.jpa.MicroServiceModels;
+import org.openecomp.policy.rest.jpa.PolicyEditorScopes;
+import org.openecomp.policy.rest.jpa.PolicyScore;
+import org.openecomp.policy.rest.jpa.PolicyVersion;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.persistence.PersistenceException;
+
+import org.openecomp.policy.common.logging.ECOMPLoggingContext;
+import org.openecomp.policy.common.logging.ECOMPLoggingUtils;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import org.openecomp.policy.xacml.api.pap.ECOMPPapEngineFactory;
+import org.openecomp.policy.xacml.api.pap.EcompPDP;
+import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
+import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine;
+
+import com.att.research.xacml.api.pap.PAPException;
+//import com.att.research.xacml.api.pap.PDP;
+//import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import com.att.research.xacml.api.pap.PDPStatus;
+import org.openecomp.policy.xacml.std.pap.StdPAPPolicy;
+import org.openecomp.policy.xacml.std.pap.StdPDP;
+import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
+import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
+import org.openecomp.policy.xacml.std.pap.StdPDPStatus;
+import org.openecomp.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChangeListener;
+import org.openecomp.policy.xacml.util.XACMLPolicyScanner;
+
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import org.openecomp.policy.common.im.AdministrativeStateException;
+import org.openecomp.policy.common.im.ForwardProgressException;
+
+//IntegrityMontitor
+import org.openecomp.policy.common.im.IntegrityMonitor;
+import org.openecomp.policy.common.im.IntegrityMonitorProperties;
+import org.openecomp.policy.common.im.StandbyStatusException;
+//IntegrityAudit
+import org.openecomp.policy.common.ia.IntegrityAudit;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+
+/**
+ * Servlet implementation class XacmlPapServlet
+ * 
+ * 
+ */
+@WebServlet(
+		description = "Implements the XACML PAP RESTful API.", 
+		urlPatterns = { "/" }, 
+		loadOnStartup=1,
+		initParams = {
+				@WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", description = "The location of the properties file holding configuration information.")
+		})
+
+public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable {
+	private static final long serialVersionUID = 1L;
+	private static final Logger logger	= FlexLogger.getLogger(XACMLPapServlet.class);
+
+	private static String CONFIG_HOME = getConfigHome();
+	private static String ACTION_HOME = getActionHome();
+
+	// audit (transaction) logger
+	private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
+
+	private IntegrityMonitor im;
+	private IntegrityAudit ia;
+
+	/*
+	 * 
+	 * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes.
+	 */
+	private PAPPolicyEngine papEngine = null;
+	/*
+	 * This PAP instance's own URL.
+	 * 
+	 * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process. 
+	 */
+	private static String papURL = null;
+
+	/*
+	 * These are the parameters needed for DB access from the PAP
+	 */
+	public static String papDbDriver = null;
+	public static String papDbUrl = null;
+	public static String papDbUser = null;
+	public static String papDbPassword = null;
+	private static Integer papTransWait = null;
+	private static Integer papTransTimeout = null;
+	private static Integer papAuditTimeout = null;
+	private static Boolean papAuditFlag = null;
+	private static Boolean papFileSystemAudit = null;
+	private static Boolean autoPushFlag = false;
+	private static String papResourceName = null;
+	private static Integer fpMonitorInterval = null; 
+	private static Integer failedCounterThreshold = null;
+	private static Integer testTransInterval = null;
+	private static Integer writeFpcInterval = null;
+	private static String papSiteName=null;
+	private static String papNodeType=null;	
+	private static String papDependencyGroups = null;
+	private String storedRequestId = null;
+	private static int papIntegrityAuditPeriodSeconds = -1;
+	private static String[] papDependencyGroupsFlatArray = null;
+
+	//The entity manager factory for JPA access
+	private EntityManagerFactory emf;
+
+	//Persistence Unit for JPA 
+	private static final String PERSISTENCE_UNIT = "XACML-PAP-REST";
+	private static final String AUDIT_PAP_PERSISTENCE_UNIT = "auditPapPU";
+
+
+	/*
+	 * List of Admin Console URLs.
+	 * Used to send notifications when configuration changes.
+	 * 
+	 * The CopyOnWriteArrayList *should* protect from concurrency errors.
+	 * This list is seldom changed but often read, so the costs of this approach make sense.
+	 */
+	private static final CopyOnWriteArrayList<String> adminConsoleURLStringList = new CopyOnWriteArrayList<String>();
+
+	// Mike M 11/24 Client Headers. 
+	private static final String ENVIRONMENT_HEADER = "Environment";
+	private static String environment = null;
+
+	/*
+	 * This thread may be invoked upon startup to initiate sending PDP policy/pip configuration when
+	 * this servlet starts. Its configurable by the admin.
+	 */
+	private Thread initiateThread = null;
+
+	/*
+	// The heartbeat thread.
+	 */
+	private static Heartbeat heartbeat = null;
+	private static Thread heartbeatThread = null;
+
+	private ECOMPLoggingContext baseLoggingContext = null;
+
+	private PolicyDBDao policyDBDao;
+	private AutoPushPolicy autoPushPolicy;
+	/**
+	 * @see HttpServlet#HttpServlet()
+	 */
+	public XACMLPapServlet() {
+		super();
+	}
+	/*
+	 * PDP FIle
+	 */
+	private static String pdpFile = null;
+	public static String getPDPFile(){
+		return XACMLPapServlet.pdpFile;
+	}
+
+	/**
+	 * @see Servlet#init(ServletConfig)
+	 */
+	public void init(ServletConfig config) throws ServletException {
+
+
+		try {
+			//
+			// Logging stuff....
+			//
+			baseLoggingContext = new ECOMPLoggingContext();
+			// fixed data that will be the same in all logging output goes here
+			try {
+				String hostname = InetAddress.getLocalHost().getCanonicalHostName();
+				baseLoggingContext.setServer(hostname);
+			} catch (UnknownHostException e) {
+				logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging");
+			}
+
+			//
+			// Initialize
+			//
+			XACMLRest.xacmlInit(config);
+			//
+			// Load the properties
+			//
+			XACMLRest.loadXacmlProperties(null, null);
+
+			/*
+			 * Retrieve the property values for db access and audits from the xacml.pap.properties
+			 */
+			//Null string occurs when a property is not present
+			try{
+				papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
+				if(papDbDriver == null){
+					throw new PAPException("papDbDriver is null");
+				}
+			}
+			catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+			try{
+				papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
+				if(papDbUrl == null){
+					throw new PAPException("papDbUrl is null");
+				}
+			} catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+			try{
+				papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
+				if(papDbUser == null){
+					throw new PAPException("papDbUser is null");
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+			try{
+				papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
+				if(papDbPassword == null){
+					throw new PAPException("papDbPassword is null");
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+
+			environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
+
+			//Integer will throw an exception of anything is missing or unrecognized
+			papTransWait = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
+			papTransTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT));
+			papAuditTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT));
+
+			//Boolean will default to false if anything is missing or unrecognized
+			papAuditFlag = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG));
+			papFileSystemAudit = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_FLAG));
+
+			//PAP Auto Push 
+			autoPushFlag = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PUSH_FLAG));
+			// if Auto push then Load with properties. 
+			if(autoPushFlag){
+				String file;
+				try{
+					file = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PUSH_FILE);
+					if(file.endsWith(".properties")){
+						autoPushPolicy = new AutoPushPolicy(file);
+					}else{
+						throw new Exception();
+					}
+				}catch(Exception e){
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Missing property or not a proper property file check for: " + XACMLRestProperties.PROP_PAP_PUSH_FILE );  
+					logger.info("Overriding the autoPushFlag to False...");
+					autoPushFlag = false;
+				}
+			}
+
+			try{
+				papResourceName = XACMLProperties.getProperty(XACMLRestProperties.PAP_RESOURCE_NAME);
+				if(papResourceName == null){
+					throw new PAPException("papResourceName is null");
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+
+			try{
+				papSiteName = XACMLProperties.getProperty(XACMLRestProperties.PAP_SITE_NAME);
+				if(papSiteName == null){
+					throw new PAPException("papSiteName is null");
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+			try{
+				papNodeType = XACMLProperties.getProperty(XACMLRestProperties.PAP_NODE_TYPE);
+				if(papNodeType == null){
+					throw new PAPException("papNodeType is null");
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+			try{
+				papDependencyGroups = XACMLProperties.getProperty(XACMLRestProperties.PAP_DEPENDENCY_GROUPS);
+				if(papDependencyGroups == null){
+					throw new PAPException("papDependencyGroups is null");
+				}
+				//Now we have flattened the array into a simple comma-separated list
+				papDependencyGroupsFlatArray = papDependencyGroups.split("[;,]");
+
+				//clean up the entries
+				for (int i = 0 ; i < papDependencyGroupsFlatArray.length ; i ++){
+					papDependencyGroupsFlatArray[i] = papDependencyGroupsFlatArray[i].trim();
+				}
+				try{
+					if(XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS) != null){
+						papIntegrityAuditPeriodSeconds = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS).trim());
+					}else{
+						//nothing to do.  The parameter is optional
+					}
+				}catch(Exception e){
+					String msg = "integrity_audit_period_seconds ";
+					logger.error("\n\nERROR: " + msg + "Bad property entry: " + e.getMessage() + "\n");
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: " + msg +"Bad property entry");
+					throw e;
+				}
+			}catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR: Bad property entry");
+				throw e;
+			}
+
+			//Integer will throw an exception of anything is missing or unrecognized
+			fpMonitorInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL));
+			failedCounterThreshold = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD));
+			testTransInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL));
+			writeFpcInterval = Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL));
+
+			logger.debug("\n\n\n**************************************"
+					+ "\n**************************************"
+					+ "\n"
+					+ "\n   papDbDriver = " + papDbDriver
+					+ "\n   papDbUrl = " + papDbUrl
+					+ "\n   papDbUser = " + papDbUser
+					+ "\n   papDbPassword = " + papDbPassword
+					+ "\n   papTransWait = " + papTransWait
+					+ "\n   papTransTimeout = " + papTransTimeout
+					+ "\n   papAuditTimeout = " + papAuditTimeout
+					+ "\n   papAuditFlag = " + papAuditFlag
+					+ "\n   papFileSystemAudit = " + papFileSystemAudit
+					+ "\n	autoPushFlag = " + autoPushFlag
+					+ "\n	papResourceName = " + papResourceName
+					+ "\n	fpMonitorInterval = " + fpMonitorInterval
+					+ "\n	failedCounterThreshold = " + failedCounterThreshold
+					+ "\n	testTransInterval = " + testTransInterval
+					+ "\n	writeFpcInterval = " + writeFpcInterval
+					+ "\n	papSiteName = " + papSiteName
+					+ "\n	papNodeType = " + papNodeType
+					+ "\n	papDependencyGroupsList = " + papDependencyGroups
+					+ "\n   papIntegrityAuditPeriodSeconds = " + papIntegrityAuditPeriodSeconds
+					+ "\n\n**************************************"
+					+ "\n**************************************");
+
+			//
+			// Pull custom persistence settings
+			//
+
+			Properties properties;
+			try {
+				properties = XACMLProperties.getProperties();//XACMLRestProperties.getProperties();
+				logger.debug("\n\n\n**************************************"
+						+ "\n**************************************"
+						+ "\n\n"
+						+ "properties = " + properties
+						+ "\n\n**************************************");
+
+			} catch (IOException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " Error loading properties with: "
+						+ "XACMLProperties.getProperties()");
+				throw new ServletException(e.getMessage(), e.getCause());
+			}
+
+			// Create an IntegrityMonitor
+			im = IntegrityMonitor.getInstance(papResourceName,properties);
+
+			// Create an IntegrityAudit
+			ia = new IntegrityAudit(papResourceName, AUDIT_PAP_PERSISTENCE_UNIT, properties);
+			ia.startAuditThread();
+
+			//
+			// Create the entity manager factory
+			//
+			emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties);
+			//
+			// Did it get created?
+			//
+			if (emf == null) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Error creating entity manager factory with persistence unit: "
+						+ PERSISTENCE_UNIT);
+				throw new ServletException("Unable to create Entity Manager Factory");
+			}
+			//
+			// we are about to call the PDPs and give them their configuration.
+			// To do that we need to have the URL of this PAP so we can construct the Policy file URLs
+			//
+			XACMLPapServlet.papURL = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
+			/*
+			 * Create the PolicyDBDao singleton
+			 */		
+			//Create the policyDBDao
+			policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(getEmf());
+			boolean performFileToDatabaseAudit = false;
+			if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG))){
+				if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_FLAG))){
+					//get an AuditTransaction to lock out all other transactions
+					PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction();
+					policyDBDao.auditLocalFileSystem();
+					//release the transaction lock
+					auditTrans.close();
+				}else{
+					performFileToDatabaseAudit = true;					
+				}
+			}
+
+
+
+			//
+			// Load our PAP engine, first create a factory
+			//
+			ECOMPPapEngineFactory factory = ECOMPPapEngineFactory.newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY));
+			//
+			// The factory knows how to go about creating a PAP Engine
+			//
+			this.papEngine = (PAPPolicyEngine) factory.newEngine();
+			PolicyDBDaoTransaction addNewGroup = null;
+			try{
+
+				if(((org.openecomp.policy.xacml.std.pap.StdEngine)papEngine).wasDefaultGroupJustAdded){
+					addNewGroup = policyDBDao.getNewTransaction();
+					EcompPDPGroup group = papEngine.getDefaultGroup();
+					addNewGroup.createGroup(group.getId(), group.getName(), group.getDescription(), "automaticallyAdded");
+					addNewGroup.commitTransaction();
+					addNewGroup = policyDBDao.getNewTransaction();					
+					addNewGroup.changeDefaultGroup(group, "automaticallyAdded");
+					addNewGroup.commitTransaction();				
+				}
+
+			} catch(Exception e){
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Error creating new default group in the database");
+				if(addNewGroup != null){
+					addNewGroup.rollbackTransaction();
+				}
+			}
+
+			policyDBDao.setPapEngine((PAPPolicyEngine) this.papEngine);
+
+
+			if(performFileToDatabaseAudit){
+				//get an AuditTransaction to lock out all other transactions
+				PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction();
+				policyDBDao.auditLocalDatabase((PAPPolicyEngine) this.papEngine);
+				//release the transaction lock
+				auditTrans.close();
+			}
+
+			//
+			// PDPId File location 
+			//
+			XACMLPapServlet.pdpFile = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_IDFILE);
+			if (XACMLPapServlet.pdpFile == null) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + 
+						" The PDP Id Authentication File Property is not valid: "
+						+ XACMLRestProperties.PROP_PDP_IDFILE);
+				throw new PAPException("The PDP Id Authentication File Property :"+ XACMLRestProperties.PROP_PDP_IDFILE+ " is not Valid. ");
+			}
+			//
+			// Sanity check that a URL was defined somewhere, its essential.
+			//
+			// How to check that its valid? We can validate the form, but since we are in the init() method we
+			// are not fully loaded yet so we really couldn't ping ourself to see if the URL will work. One
+			// will have to look for errors in the PDP logs to determine if they are failing to initiate a
+			// request to this servlet.
+			//
+			if (XACMLPapServlet.papURL == null) {
+
+				throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + XACMLPapServlet.papURL);
+			}
+			//
+			// Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration
+			// to all its known PDP nodes.
+			//
+			// Note: parseBoolean will return false if there is no property defined. This is fine for a default.
+			//
+			if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) {
+				this.initiateThread = new Thread(this);
+				this.initiateThread.start();
+			}
+			//
+			// After startup, the PAP does Heartbeats to each of the PDPs periodically
+			//
+			XACMLPapServlet.heartbeat = new Heartbeat((PAPPolicyEngine) this.papEngine);
+			XACMLPapServlet.heartbeatThread = new Thread(XACMLPapServlet.heartbeat);
+			XACMLPapServlet.heartbeatThread.start();
+		} catch (FactoryException | PAPException e) {
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine");
+			throw new ServletException (XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; error: "+e);
+		} catch (Exception e) {
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine - unexpected error");
+			throw new ServletException (XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; unexpected error: "+e);		}
+	}
+
+	/**
+	 * Thread used only during PAP startup to initiate change messages to all known PDPs.
+	 * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced.
+	 */
+	@Override
+	public void run() {
+		//
+		// send the current configuration to all the PDPs that we know about
+		//
+		changed();
+	}
+
+
+	/**
+	 * @see Servlet#destroy()
+	 * 
+	 * Depending on how this servlet is run, we may or may not care about cleaning up the resources.
+	 * For now we assume that we do care.
+	 */
+	public void destroy() {
+		//
+		// Make sure our threads are destroyed
+		//
+		if (XACMLPapServlet.heartbeatThread != null) {
+			//
+			// stop the heartbeat
+			//
+			try {
+				if (XACMLPapServlet.heartbeat != null) {
+					XACMLPapServlet.heartbeat.terminate();
+				}
+				XACMLPapServlet.heartbeatThread.interrupt();
+				XACMLPapServlet.heartbeatThread.join();
+			} catch (InterruptedException e) {
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping heartbeat");
+			}
+		}
+		if (this.initiateThread != null) {
+			try {
+				this.initiateThread.interrupt();
+				this.initiateThread.join();
+			} catch (InterruptedException e) {
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Error stopping thread");
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * Called by:
+	 * 	- PDP nodes to register themselves with the PAP, and
+	 * 	- Admin Console to make changes in the PDP Groups.
+	 * 
+	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		ECOMPLoggingContext loggingContext = ECOMPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
+
+		loggingContext.transactionStarted();
+		loggingContext.setServiceName("PAP.post"); // we may set a more specific value later
+		if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
+			UUID requestID = UUID.randomUUID();
+			loggingContext.setRequestID(requestID.toString());
+			PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPost) so we generated one");
+		} else {
+			PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPost)");
+		}
+		// dummy metric.log example posted below as proof of concept
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 1 of 2");
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 2 of 2");
+		// dummy metric.log example posted above as proof of concept
+		PolicyDBDaoTransaction pdpTransaction = null;
+
+		//This im.startTransaction() covers all Post transactions
+		try {
+			im.startTransaction();
+		} catch (AdministrativeStateException ae){
+			String message = "POST interface called for PAP " + papResourceName + " but it has an Administrative"
+					+ " state of " + im.getStateManager().getAdminState()
+					+ "\n Exception Message: " + ae.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}catch (StandbyStatusException se) {
+			se.printStackTrace();
+			String message = "POST interface called for PAP " + papResourceName + " but it has a Standby Status"
+					+ " of " + im.getStateManager().getStandbyStatus()
+					+ "\n Exception Message: " + se.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}
+
+		try {
+
+			XACMLRest.dumpRequest(request);
+
+			// since getParameter reads the content string, explicitly get the content before doing that.
+			// Simply getting the inputStream seems to protect it against being consumed by getParameter.
+			request.getInputStream();
+
+
+			String groupId = request.getParameter("groupId");
+			String apiflag = request.getParameter("apiflag");
+
+			if (groupId != null) {
+				// Is this from the Admin Console or API?
+				if(apiflag!=null) {
+					if (apiflag.equalsIgnoreCase("api")) {
+						// this is from the API so we need to check the client credentials before processing the request
+						if(authorizeRequest(request)){
+							doACPost(request, response, groupId, loggingContext);
+							// Mike B - ended loggingContext transacton & added EELF 'Success' EELF Audit.log message
+							loggingContext.transactionEnded();
+							PolicyLogger.audit("Transaction Ended Successfully");
+							im.endTransaction();
+							return;
+						} else {
+							String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+							PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+							loggingContext.transactionEnded();
+
+							PolicyLogger.audit("Transaction Failed - See Error.log");
+
+							response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+							im.endTransaction();
+							return;
+						}
+					}
+				}
+
+				// this is from the Admin Console, so handle separately
+				doACPost(request, response, groupId, loggingContext);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Ended Successfully");
+				im.endTransaction();
+				return;
+
+			}
+
+
+			//
+			//  Request is from a PDP.
+			//	It is coming up and asking for its config
+			//
+			loggingContext.setServiceName("PDP:PAP.register");
+
+
+			//
+			// Get the PDP's ID
+			//
+			String id = this.getPDPID(request);
+			String jmxport = this.getPDPJMX(request);
+			//logger.info("doPost from: " + id);
+			logger.info("Request(doPost) from PDP coming up: " + id);
+			//
+			// Get the PDP Object
+			//
+			EcompPDP pdp = this.papEngine.getPDP(id);
+			//
+			// Is it known?
+			//
+			if (pdp == null) {
+				logger.info("Unknown PDP: " + id);
+				// PDP ID Check is performed Here. 
+				if(CheckPDP.validateID(id)){
+					pdpTransaction = policyDBDao.getNewTransaction();
+					try {
+						//this.papEngine.newPDP(id, this.papEngine.getDefaultGroup(), id, "Registered on first startup");
+						pdpTransaction.addPdpToGroup(id, this.papEngine.getDefaultGroup().getId(), id, "Registered on first startup", Integer.parseInt(jmxport), "PDP autoregister");
+						this.papEngine.newPDP(id, this.papEngine.getDefaultGroup(), id, "Registered on first startup", Integer.parseInt(jmxport));
+					} catch (NullPointerException | PAPException | IllegalArgumentException | IllegalStateException | PersistenceException e) {
+						pdpTransaction.rollbackTransaction();
+						String message = "Failed to create new PDP for id: " + id;
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " " + message);
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+						im.endTransaction();
+						return;
+					}
+					// get the PDP we just created
+					pdp = this.papEngine.getPDP(id);
+					if (pdp == null) {
+						if(pdpTransaction != null){
+							pdpTransaction.rollbackTransaction();
+						}
+						String message = "Failed to create new PDP for id: " + id;
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+						im.endTransaction();
+						return;
+					}
+				} else {
+					String message = "PDP is Unauthorized to Connect to PAP: "+ id;
+					PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+					loggingContext.transactionEnded();
+					response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "PDP not Authorized to connect to this PAP. Please contact the PAP Admin for registration.");
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					im.endTransaction();
+					return;
+				}
+				// get the PDP we just created
+				pdp = this.papEngine.getPDP(id);
+				if (pdp == null) {
+					if(pdpTransaction != null){
+						pdpTransaction.rollbackTransaction();
+					}
+					String message = "Failed to create new PDP for id: " + id;
+					PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+					loggingContext.transactionEnded();
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+					im.endTransaction();
+					return;
+				}
+				try{
+					pdpTransaction.commitTransaction();
+				} catch(Exception e){
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", "Could not commit transaction to put pdp in the database");
+				}
+			}
+
+			if (jmxport != null && jmxport != ""){
+				((StdPDP) pdp).setJmxPort(Integer.valueOf(jmxport));
+			}
+
+			//
+			// Get the PDP's Group
+			//
+			EcompPDPGroup group = this.papEngine.getPDPGroup((EcompPDP) pdp);
+			if (group == null) {
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " PDP not associated with any group, even the default");
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "PDP not associated with any group, even the default");
+				im.endTransaction();
+				return;
+			}
+			//
+			// Determine what group the PDP node is in and get
+			// its policy/pip properties.
+			//
+			Properties policies = group.getPolicyProperties();
+			Properties pipconfig = group.getPipConfigProperties();
+			//
+			// Get the current policy/pip configuration that the PDP has
+			//
+			Properties pdpProperties = new Properties();
+			pdpProperties.load(request.getInputStream());
+			logger.info("PDP Current Properties: " + pdpProperties.toString());
+			logger.info("Policies: " + (policies != null ? policies.toString() : "null"));
+			logger.info("Pip config: " + (pipconfig != null ? pipconfig.toString() : "null"));
+			//
+			// Validate the node's properties
+			//
+			boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties);
+			//
+			// Send back current configuration
+			//
+			if (isCurrent == false) {
+				//
+				// Tell the PDP we are sending back the current policies/pip config
+				//
+				logger.info("PDP configuration NOT current.");
+				if (policies != null) {
+					//
+					// Put URL's into the properties in case the PDP needs to
+					// retrieve them.
+					//
+					this.populatePolicyURL(request.getRequestURL(), policies);
+					//
+					// Copy the properties to the output stream
+					//
+					policies.store(response.getOutputStream(), "");
+				}
+				if (pipconfig != null) {
+					//
+					// Copy the properties to the output stream
+					//
+					pipconfig.store(response.getOutputStream(), "");
+				}
+				//
+				// We are good - and we are sending them information
+				//
+				response.setStatus(HttpServletResponse.SC_OK);
+
+				setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+			} else {
+				//
+				// Tell them they are good
+				//
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+
+				setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+
+			}
+			//
+			// tell the AC that something changed
+			//
+			notifyAC();
+			loggingContext.transactionEnded();
+			auditLogger.info("Success");
+			PolicyLogger.audit("Transaction Ended Successfully");
+		} catch (PAPException e) {
+			if(pdpTransaction != null){
+				pdpTransaction.rollbackTransaction();
+			}
+			logger.debug(XACMLErrorConstants.ERROR_PROCESS_FLOW + "POST exception: " + e, e);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response.sendError(500, e.getMessage());
+			im.endTransaction();
+			return;
+		}
+		//Catch anything that fell through
+		loggingContext.transactionEnded();
+		PolicyLogger.audit("Transaction Ended");
+		im.endTransaction();
+	}
+
+	/**
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		ECOMPLoggingContext loggingContext = ECOMPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
+		loggingContext.transactionStarted();
+		loggingContext.setServiceName("PAP.get"); // we may set a more specific value later
+		if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
+			UUID requestID = UUID.randomUUID();
+			loggingContext.setRequestID(requestID.toString());
+			PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doGet) so we generated one");
+		} else {
+			PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doGet)");
+		}
+		// dummy metric.log example posted below as proof of concept
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 1 of 2");
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 2 of 2");
+		// dummy metric.log example posted above as proof of concept
+		try {
+			XACMLRest.dumpRequest(request);
+			String pathInfo = request.getRequestURI();
+			logger.info("path info: " + pathInfo);
+			if (pathInfo != null){
+				//DO NOT do a im.startTransaction for the test request
+				if (pathInfo.equals("/pap/test")) {
+					logger.info("Test request received");
+					try {
+						im.evaluateSanity();
+						//If we make it this far, all is well
+						String message = "GET:/pap/test called and PAP " + papResourceName + " is OK";
+						logger.info(message);
+						loggingContext.transactionEnded();
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.setStatus(HttpServletResponse.SC_OK);
+						return;
+					}catch (ForwardProgressException fpe){
+						//No forward progress is being made
+						String message = "GET:/pap/test called and PAP " + papResourceName + " is not making forward progress."
+								+ " Exception Message: " + fpe.getMessage();
+						logger.info(message);
+						PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+						return;
+					}catch (AdministrativeStateException ase){
+						//Administrative State is locked
+						String message = "GET:/pap/test called and PAP " + papResourceName + " Administrative State is LOCKED "
+								+ " Exception Message: " + ase.getMessage();
+						logger.info(message);
+						PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+						return;
+					}catch (StandbyStatusException sse){
+						//Administrative State is locked
+						String message = "GET:/pap/test called and PAP " + papResourceName + " Standby Status is NOT PROVIDING SERVICE "
+								+ " Exception Message: " + sse.getMessage();
+						logger.info(message);
+						PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+						return;
+					}catch (Exception e) {
+						//A subsystem is not making progress, is locked, standby or is not responding
+						String eMsg = e.getMessage();
+						if(eMsg == null){
+							eMsg = "No Exception Message";
+						}
+						String message = "GET:/pap/test called and PAP " + papResourceName + " has had a subsystem failure."
+								+ " Exception Message: " + eMsg;
+						logger.info(message);
+						PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						//Get the specific list of subsystems that failed
+						String ssFailureList = null;
+						for(String failedSS : papDependencyGroupsFlatArray){
+							if(eMsg.contains(failedSS)){
+								if(ssFailureList == null){
+									ssFailureList = failedSS;
+								}else{
+									ssFailureList = ssFailureList.concat(","+failedSS);
+								}
+							}
+						}
+						if(ssFailureList == null){
+							ssFailureList = "UnknownSubSystem";
+						}
+						response.addHeader("X-ECOMP-SubsystemFailure", ssFailureList);
+						response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+						return;
+					}
+				}
+			}
+
+			//This im.startTransaction() covers all other Get transactions
+			try {
+				im.startTransaction();
+			} catch (AdministrativeStateException ae){
+				String message = "GET interface called for PAP " + papResourceName + " but it has an Administrative"
+						+ " state of " + im.getStateManager().getAdminState()
+						+ "\n Exception Message: " + ae.getMessage();
+				logger.info(message);
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+				return;
+			}catch (StandbyStatusException se) {
+				se.printStackTrace();
+				String message = "GET interface called for PAP " + papResourceName + " but it has a Standby Status"
+						+ " of " + im.getStateManager().getStandbyStatus()
+						+ "\n Exception Message: " + se.getMessage();
+				logger.info(message);
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+				return;
+			}
+
+
+			// Request from the API to get the gitPath
+			String apiflag = request.getParameter("apiflag");
+			if (apiflag!=null) {
+				if(authorizeRequest(request)){
+
+
+					// Request from the API to get the gitPath
+					if (apiflag.equalsIgnoreCase("gitPath")) {
+						getGitPath(request, response);
+						// Mike B - ended loggingContext transacton & added EELF 'Success' EELF Audit.log message
+						loggingContext.transactionEnded();
+						PolicyLogger.audit("Transaction Ended Successfully");
+						im.endTransaction();
+						return;
+					}
+
+					// Request from the API to get the ActiveVersion from the PolicyVersion table
+					if (apiflag.equalsIgnoreCase("version")){
+						getActiveVersion(request, response);
+						loggingContext.transactionEnded();
+						PolicyLogger.audit("Transaction Ended Successfully");
+						im.endTransaction();
+						return;
+					}
+
+					// Request from the API to get the URI from the gitpath
+					if (apiflag.equalsIgnoreCase("uri")){
+						getSelectedURI(request, response);
+						loggingContext.transactionEnded();
+						PolicyLogger.audit("Transaction Ended Successfully");
+						im.endTransaction();
+						return;
+					}
+
+				} else {
+					String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+					PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+					im.endTransaction();
+					return;
+				}
+
+			}
+
+
+			// Is this from the Admin Console?
+			String groupId = request.getParameter("groupId");
+			if (groupId != null) {
+				// this is from the Admin Console, so handle separately
+				doACGet(request, response, groupId, loggingContext);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Ended Successfully");
+				im.endTransaction();
+				return;
+			}
+
+			//
+			// Get the PDP's ID
+			//
+			String id = this.getPDPID(request);
+			logger.info("doGet from: " + id);
+			//
+			// Get the PDP Object
+			//
+			EcompPDP pdp = this.papEngine.getPDP(id);
+			//
+			// Is it known?
+			//
+			if (pdp == null) {
+				//
+				// Check if request came from localhost
+				//
+				if (request.getRemoteHost().equals("localhost") ||
+						request.getRemoteHost().equals("127.0.0.1") ||
+						request.getRemoteHost().equals(request.getLocalAddr())) {
+					//
+					// Return status information - basically all the groups
+					//
+					loggingContext.setServiceName("PAP.getGroups");
+					Set<EcompPDPGroup> groups = papEngine.getEcompPDPGroups();
+
+					// convert response object to JSON and include in the response
+					ObjectMapper mapper = new ObjectMapper();
+					mapper.writeValue(response.getOutputStream(),  groups);
+					response.setHeader("content-type", "application/json");
+					response.setStatus(HttpServletResponse.SC_OK);
+					loggingContext.transactionEnded();
+					PolicyLogger.audit("Transaction Ended Successfully");
+					im.endTransaction();
+					return;
+				}
+				String message = "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr();
+				PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+				im.endTransaction();
+				return;
+			}
+
+			loggingContext.setServiceName("PAP.getPolicy");
+
+			//
+			// Get the PDP's Group
+			//
+			EcompPDPGroup group = this.papEngine.getPDPGroup((EcompPDP) pdp);
+			if (group == null) {
+				String message = "No group associated with pdp " + pdp.getId();
+				logger.warn(XACMLErrorConstants.ERROR_PERMISSIONS + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
+				im.endTransaction();
+				return;
+			}
+			//
+			// Which policy do they want?
+			//
+			String policyId = request.getParameter("id");
+			if (policyId == null) {
+				String message = "Did not specify an id for the policy";
+				logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				im.endTransaction();
+				return;
+			}
+			PDPPolicy policy = group.getPolicy(policyId);
+			if (policy == null) {
+				String message = "Unknown policy: " + policyId;
+				logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				im.endTransaction();
+				return;
+			}
+			//
+			// Get its stream
+			//
+			logger.warn("PolicyDebugging: Policy Validity: " + policy.isValid() + "\n "
+					+ "Policy Name : " + policy.getName() + "\n Policy URI: " + policy.getLocation().toString() );
+			try (InputStream is = policy.getStream(); OutputStream os = response.getOutputStream()) {
+				//
+				// Send the policy back
+				//
+				IOUtils.copy(is, os);
+
+				response.setStatus(HttpServletResponse.SC_OK);
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+			} catch (PAPException e) {
+				String message = "Failed to open policy id " + policyId;
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+			}
+		}  catch (PAPException e) {
+			PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", " GET exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(500, e.getMessage());
+			im.endTransaction();
+			return;
+		}
+		loggingContext.transactionEnded();
+		PolicyLogger.audit("Transaction Ended");
+		im.endTransaction();
+	}
+
+
+	/**
+	 * Requests from the PolicyEngine API to update the PDP Group with pushed policy
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId, ECOMPLoggingContext loggingContext) throws IOException {
+		PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
+		try {
+
+
+			// for PUT operations the group may or may not need to exist before the operation can be done
+			StdPDPGroup group = (StdPDPGroup) papEngine.getGroup(groupId);
+
+			// get the request content into a String
+			String json = null;
+
+			// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+			java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+			scanner.useDelimiter("\\A");
+			json =  scanner.hasNext() ? scanner.next() : "";
+			scanner.close();
+			logger.info("JSON request from PolicyEngine API: " + json);
+
+			// convert Object sent as JSON into local object
+			ObjectMapper mapper = new ObjectMapper();
+
+			Object objectFromJSON = mapper.readValue(json, StdPDPPolicy.class);
+
+			StdPDPPolicy policy = (StdPDPPolicy) objectFromJSON;
+
+			Set<PDPPolicy> policies = new HashSet<PDPPolicy>();
+
+			if(policy!=null){
+				policies.add(policy);
+			}
+
+			//Get the current policies from the Group and Add the new one
+			Set<PDPPolicy> currentPoliciesInGroup = new HashSet<PDPPolicy>();
+			currentPoliciesInGroup = group.getPolicies();
+
+			//If the selected policy is in the group we must remove it because the name is default
+			Iterator<PDPPolicy> policyIterator = policies.iterator();
+			logger.debug("policyIterator....." + policies);
+			while (policyIterator.hasNext()) {
+				PDPPolicy selPolicy = policyIterator.next();
+				for (PDPPolicy existingPolicy : currentPoliciesInGroup) {
+					if (existingPolicy.getId().equals(selPolicy.getId())) {
+						group.removePolicyFromGroup(existingPolicy);
+						logger.debug("Removing policy: " + existingPolicy);
+						break;
+					}
+				}
+			}
+
+			if(currentPoliciesInGroup!=null){
+				policies.addAll(currentPoliciesInGroup);
+			}
+			group.setPolicies(policies);
+
+			// Assume that this is an update of an existing PDP Group
+			loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
+
+			try{
+				acPutTransaction.updateGroup(group, "XACMLPapServlet.doACPut");
+			} catch(Exception e){
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
+						+"group="+group.getId());
+				throw new PAPException(e.getMessage());	
+			}
+
+			papEngine.updateGroup(group);
+			response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+			response.addHeader("operation", "push");
+			response.addHeader("policyId", policy.getId());
+			response.addHeader("groupId", groupId);
+			if (logger.isDebugEnabled()) {		
+				logger.debug("Group '" + group.getId() + "' updated");
+			}
+
+			acPutTransaction.commitTransaction();
+
+			notifyAC();
+
+			// Group changed, which might include changing the policies	
+			groupChanged(group);
+			loggingContext.transactionEnded();
+			auditLogger.info("Success");
+			PolicyLogger.audit("Transaction Ended Successfully");
+			return;
+		} catch (PAPException e) {
+			acPutTransaction.rollbackTransaction();
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Exception in request to update group from API - See Error.log on on the PAP.";
+			response.sendError(500, e.getMessage());
+			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+			response.addHeader("error","addGroupError");
+			response.addHeader("message", message);
+			return;
+		}
+
+	}
+
+	private void getActiveVersion(HttpServletRequest request, HttpServletResponse response) {
+		//Setup EntityManager to communicate with the PolicyVersion table of the DB
+		EntityManager em = null;
+		em = (EntityManager) emf.createEntityManager();
+
+		if (em==null){
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Error creating entity manager with persistence unit: " + PERSISTENCE_UNIT);
+			try {
+				throw new Exception("Unable to create Entity Manager Factory");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		String policyScope = request.getParameter("policyScope");
+		String filePrefix = request.getParameter("filePrefix");
+		String policyName = request.getParameter("policyName");
+
+		String pvName = policyScope + File.separator + filePrefix + policyName;
+		int activeVersion = 0;
+
+
+		//Get the Active Version to use in the ID
+		em.getTransaction().begin();
+		Query query = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
+		query.setParameter("pname", pvName);
+
+		@SuppressWarnings("rawtypes")
+		List result = query.getResultList();
+		PolicyVersion versionEntity = null;
+		if (!result.isEmpty()) {
+			versionEntity = (PolicyVersion) result.get(0);
+			em.persist(versionEntity);
+			activeVersion = versionEntity.getActiveVersion();
+			em.getTransaction().commit();
+		} else {
+			logger.debug("No PolicyVersion using policyName found");
+		}
+
+		//clean up connection
+		em.close();
+		if (String.valueOf(activeVersion)!=null || !String.valueOf(activeVersion).equalsIgnoreCase("")) {							
+			response.setStatus(HttpServletResponse.SC_OK);								
+			response.addHeader("version", String.valueOf(activeVersion));								
+		} else {						
+			response.setStatus(HttpServletResponse.SC_NOT_FOUND);								
+		}	
+
+
+	}
+
+	private void getSelectedURI(HttpServletRequest request,
+			HttpServletResponse response) {
+
+		String gitPath = request.getParameter("gitPath");
+
+		File file = new File(gitPath);
+
+		logger.debug("The fileItem is : " + file.toString());
+
+		URI selectedURI = file.toURI();
+
+		String uri = selectedURI.toString();
+
+		if (!uri.equalsIgnoreCase("")) {							
+			response.setStatus(HttpServletResponse.SC_OK);								
+			response.addHeader("selectedURI", uri);								
+		} else {						
+			response.setStatus(HttpServletResponse.SC_NOT_FOUND);								
+		}						
+	}
+
+	/*
+	 * getGitPath() method to get the gitPath using data from the JSON string 
+	 * when deleting policies using doAPIDelete()
+	 */
+	private File getPolicyFile(String policyName){
+
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+
+		//getting the fullpath of the gitPath and convert to string
+		String fullGitPath = gitPath.toAbsolutePath().toString();
+		String finalGitPath = null;
+
+		//creating the parentPath directory for the Admin Console use
+		if(fullGitPath.contains("\\")){
+			finalGitPath = fullGitPath.replace("ECOMP-PAP-REST", "ecomp-sdk-app");
+		}else{
+			finalGitPath = fullGitPath.replace("pap",  "console");
+		}
+
+		finalGitPath += File.separator + policyName;
+
+		File file = new File(finalGitPath);
+
+		return file;
+
+	}
+
+	/*
+	 * getGitPath() method to get the gitPath using data from the http request
+	 * and send back in response when pushing policies
+	 */
+	private void getGitPath(HttpServletRequest request,
+			HttpServletResponse response) {
+
+		String policyScope = request.getParameter("policyScope");
+		String filePrefix = request.getParameter("filePrefix");
+		String policyName = request.getParameter("policyName");
+		String activeVersion = request.getParameter("activeVersion");
+
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+
+		//getting the fullpath of the gitPath and convert to string
+		String fullGitPath = gitPath.toAbsolutePath().toString();
+		String finalGitPath = null;
+
+		//creating the parentPath directory for the Admin Console use
+		if(fullGitPath.contains("\\")){
+			finalGitPath = fullGitPath.replace("ECOMP-PAP-REST", "ecomp-sdk-app");
+		}else{
+			finalGitPath = fullGitPath.replace("pap",  "console");
+		}
+
+		finalGitPath += File.separator + policyScope + File.separator + filePrefix + policyName + "." + activeVersion + ".xml";
+		File file = new File(finalGitPath);
+		URI uri = file.toURI();
+		
+		//
+		// Extract XACML policy information
+		//
+		Boolean isValid = false;
+		String policyId = null;
+		String description = null;
+		String	version = null;
+
+		URL url;
+		try {
+			url = uri.toURL();
+			Object rootElement = XACMLPolicyScanner.readPolicy(url.openStream());
+			if (rootElement == null ||
+					(
+							! (rootElement instanceof PolicySetType) &&
+							! (rootElement instanceof PolicyType)
+							)	) {
+				logger.warn("No root policy element in URI: " + uri.toString() + " : " + rootElement);
+				isValid = false;
+			} else {
+				if (rootElement instanceof PolicySetType) {
+					policyId = ((PolicySetType)rootElement).getPolicySetId();
+					description = ((PolicySetType)rootElement).getDescription();
+					isValid = true;
+					version = ((PolicySetType)rootElement).getVersion();
+				} else if (rootElement instanceof PolicyType) {
+					policyId = ((PolicyType)rootElement).getPolicyId();
+					description = ((PolicyType)rootElement).getDescription();
+					version = ((PolicyType)rootElement).getVersion();
+					isValid = true;
+				} else {
+					PolicyLogger.error("Unknown root element: " + rootElement.getClass().getCanonicalName());
+				}
+			}
+		} catch (Exception e) {
+			logger.error("Exception Occured While Extracting Policy Information");
+		} 
+
+		if (!finalGitPath.equalsIgnoreCase("") || policyId!=null || description!=null || version!=null || isValid!=null) {							
+			response.setStatus(HttpServletResponse.SC_OK);								
+			response.addHeader("gitPath", finalGitPath);
+			response.addHeader("policyId", policyId);
+			response.addHeader("description", description);
+			response.addHeader("version", version);
+			response.addHeader("isValid", isValid.toString());
+		} else {						
+			response.setStatus(HttpServletResponse.SC_NOT_FOUND);								
+		}						
+
+	}
+
+	/**
+	 * Given a version string consisting of integers with dots between them, convert it into an array of ints.
+	 * 
+	 * @param version
+	 * @return
+	 * @throws NumberFormatException
+	 */
+	public static int[] versionStringToArray(String version) throws NumberFormatException {
+		if (version == null || version.length() == 0) {
+			return new int[0];
+		}
+		String[] stringArray = version.split("\\.");
+		int[] resultArray = new int[stringArray.length];
+		for (int i = 0; i < stringArray.length; i++) {
+			resultArray[i] = Integer.parseInt(stringArray[i]);
+		}
+		return resultArray;
+	}
+
+	protected String	getPDPID(HttpServletRequest request) {
+		String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID);
+		if (pdpURL == null || pdpURL.isEmpty()) {
+			//
+			// Should send back its port for identification
+			//
+			logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header");
+			pdpURL = "";
+		}
+		return  pdpURL;
+	}
+
+	protected String getPDPJMX(HttpServletRequest request) {
+		String pdpJMMX = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT);
+		if (pdpJMMX == null || pdpJMMX.isEmpty()) {
+			//
+			// Should send back its port for identification
+			//
+			logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header for JMX Port so the value of 0 is assigned");
+			return null;
+		}
+		return pdpJMMX;
+	}
+	private boolean isPDPCurrent(Properties policies, Properties pipconfig, Properties pdpProperties) {
+		String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		if (localRootPolicies == null || localReferencedPolicies == null) {
+			logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing property on PAP server: RootPolicies="+localRootPolicies+"  ReferencedPolicies="+localReferencedPolicies);
+			return false;
+		}
+		//
+		// Compare the policies and pipconfig properties to the pdpProperties
+		//
+		try {
+			//
+			// the policy properties includes only xacml.rootPolicies and 
+			// xacml.referencedPolicies without any .url entries
+			//
+			Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false);
+			Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties);
+			if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) &&
+					localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) &&
+					pdpPipConfig.equals(pipconfig)) {
+				//
+				// The PDP is current
+				//
+				return true;
+			}
+		} catch (Exception e) {
+			// we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines,
+			// or if there are policies that do not have a corresponding ".url" property.
+			// Either of these cases means that the PDP is not up-to-date, so just drop-through to return false.
+			PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPapServlet", " PDP Error");
+		}
+		return false;
+	}
+
+	private void populatePolicyURL(StringBuffer urlPath, Properties policies) {
+		String lists[] = new String[2];
+		lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES);
+		lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES);
+		for (String list : lists) {
+			if (list != null && list.isEmpty() == false) {
+				for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(list)) {
+					String url = urlPath + "?id=" + id;
+					logger.info("Policy URL for " + id + ": " + url);
+					policies.setProperty(id + ".url", url);
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		ECOMPLoggingContext loggingContext = ECOMPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
+		storedRequestId = loggingContext.getRequestID();
+		loggingContext.transactionStarted();
+		loggingContext.setServiceName("PAP.put"); // we may set a more specific value later
+		if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
+			UUID requestID = UUID.randomUUID();
+			loggingContext.setRequestID(requestID.toString());
+			PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPut) so we generated one");
+		} else {
+			PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPut)");
+		}
+		// dummy metric.log example posted below as proof of concept
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 1 of 2");
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 2 of 2");
+		//This im.startTransaction() covers all Put transactions
+		try {
+			im.startTransaction();
+		} catch (AdministrativeStateException ae){
+			String message = "PUT interface called for PAP " + papResourceName + " but it has an Administrative"
+					+ " state of " + im.getStateManager().getAdminState()
+					+ "\n Exception Message: " + ae.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}catch (StandbyStatusException se) {
+			se.printStackTrace();
+			String message = "PUT interface called for PAP " + papResourceName + " but it has a Standby Status"
+					+ " of " + im.getStateManager().getStandbyStatus()
+					+ "\n Exception Message: " + se.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}
+
+		XACMLRest.dumpRequest(request);
+
+		//
+		// since getParameter reads the content string, explicitly get the content before doing that.
+		// Simply getting the inputStream seems to protect it against being consumed by getParameter.
+		//
+		request.getInputStream();
+
+		//need to check if request is from the API or Admin console
+		String apiflag = request.getParameter("apiflag");
+
+		//This would occur if a PolicyDBDao notification was received
+		String policyDBDaoRequestUrl = request.getParameter("policydbdaourl");
+		if(policyDBDaoRequestUrl != null){
+			String policyDBDaoRequestEntityId = request.getParameter("entityid");
+			//String policyDBDaoRequestEntityType = request.getParameter("entitytype");
+			String policyDBDaoRequestEntityType = request.getParameter("entitytype");
+			String policyDBDaoRequestExtraData = request.getParameter("extradata");
+			if(policyDBDaoRequestEntityId == null || policyDBDaoRequestEntityType == null){
+				response.sendError(400, "entityid or entitytype not supplied");
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Ended Successfully");
+				im.endTransaction();
+				return;
+			}
+			policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl,policyDBDaoRequestEntityId,policyDBDaoRequestEntityType,policyDBDaoRequestExtraData,this);			
+			response.setStatus(200);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+		}
+
+		//This would occur if we received a notification of a policy creation or update
+		String policyToCreateUpdate = request.getParameter("policyToCreateUpdate");
+		if(policyToCreateUpdate != null){
+			if(logger.isDebugEnabled()){
+				logger.debug("\nXACMLPapServlet.doPut() - before decoding"
+						+ "\npolicyToCreateUpdate = " + policyToCreateUpdate);
+			}
+			//decode it
+			try{
+				policyToCreateUpdate = URLDecoder.decode(policyToCreateUpdate, "UTF-8");
+				if(logger.isDebugEnabled()){
+					logger.debug("\nXACMLPapServlet.doPut() - after decoding"
+							+ "\npolicyToCreateUpdate = " + policyToCreateUpdate);
+				}
+			} catch(UnsupportedEncodingException e){
+				PolicyLogger.error("\nXACMLPapServlet.doPut() - Unsupported URL encoding of policyToCreateUpdate (UTF-8)"
+						+ "\npolicyToCreateUpdate = " + policyToCreateUpdate);
+				response.sendError(500,"policyToCreateUpdate encoding not supported"
+						+ "\nfailure with the following exception: " + e);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See error.log");
+				im.endTransaction();
+				return;
+			}
+
+			//send it to PolicyDBDao
+			PolicyDBDaoTransaction createUpdateTransaction = policyDBDao.getNewTransaction();
+			try{
+				createUpdateTransaction.createPolicy(policyToCreateUpdate, "XACMLPapServlet.doPut");
+			}catch(Exception e){
+				createUpdateTransaction.rollbackTransaction();
+				response.sendError(500,"createUpdateTransaction.createPolicy(policyToCreateUpdate, XACMLPapServlet.doPut) "
+						+ "\nfailure with the following exception: " + e);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See error.log");
+				im.endTransaction();
+				return;
+			}
+			createUpdateTransaction.commitTransaction();
+			// Before sending Ok. Lets call AutoPush. 
+			if(autoPushFlag){
+				Set<StdPDPGroup> changedGroups = autoPushPolicy.checkGroupsToPush(policyToCreateUpdate,  this.papEngine);
+				if(!changedGroups.isEmpty()){
+					for(StdPDPGroup group: changedGroups){
+						try{
+							papEngine.updateGroup(group);
+							if (logger.isDebugEnabled()) {		
+								logger.debug("Group '" + group.getId() + "' updated");
+							}
+							notifyAC();
+							// Group changed, which might include changing the policies	
+							groupChanged(group);
+						}catch(Exception e){
+							PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Failed to Push policy. ");
+						}
+					}
+				}
+			}
+			response.setStatus(HttpServletResponse.SC_OK);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+		}
+
+		/*
+		 * Request for Micro Service Import
+		 */
+		String microServiceCreation = request.getParameter("importService");
+		if (microServiceCreation != null) {
+			if(authorizeRequest(request)){   
+				if (microServiceCreation.contains("MICROSERVICE")){
+					doImportMicroServicePut(request, response);
+					im.endTransaction();
+					return;
+				}
+			} else {
+				String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+				logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + message );
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+				return;
+			}
+		}
+		//This would occur if we received a notification of a policy rename from AC
+		String oldPolicyName = request.getParameter("oldPolicyName");
+		String newPolicyName = request.getParameter("newPolicyName");
+		if(oldPolicyName != null && newPolicyName != null){
+			if(logger.isDebugEnabled()){
+				logger.debug("\nXACMLPapServlet.doPut() - before decoding"
+						+ "\npolicyToCreateUpdate = " + " ");
+			}
+			//decode it
+			try{
+				oldPolicyName = URLDecoder.decode(oldPolicyName, "UTF-8");
+				newPolicyName = URLDecoder.decode(newPolicyName, "UTF-8");
+				if(logger.isDebugEnabled()){
+					logger.debug("\nXACMLPapServlet.doPut() - after decoding"
+							+ "\npolicyToCreateUpdate = " + " ");
+				}
+			} catch(UnsupportedEncodingException e){
+				PolicyLogger.error("\nXACMLPapServlet.doPut() - Unsupported URL encoding of policyToCreateUpdate (UTF-8)"
+						+ "\npolicyToCreateUpdate = " + " ");
+				response.sendError(500,"policyToCreateUpdate encoding not supported"
+						+ "\nfailure with the following exception: " + e);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See error.log");
+				im.endTransaction();
+				return;
+			}
+			//send it to PolicyDBDao
+			PolicyDBDaoTransaction renameTransaction = policyDBDao.getNewTransaction();
+			try{
+				renameTransaction.renamePolicy(oldPolicyName,newPolicyName, "XACMLPapServlet.doPut");
+			}catch(Exception e){
+				renameTransaction.rollbackTransaction();
+				response.sendError(500,"createUpdateTransaction.createPolicy(policyToCreateUpdate, XACMLPapServlet.doPut) "
+						+ "\nfailure with the following exception: " + e);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See error.log");
+				im.endTransaction();
+				return;
+			}
+			renameTransaction.commitTransaction();
+			response.setStatus(HttpServletResponse.SC_OK);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+		}
+
+
+		//
+		// See if this is Admin Console registering itself with us
+		//
+		String acURLString = request.getParameter("adminConsoleURL");
+		if (acURLString != null) {
+			loggingContext.setServiceName("AC:PAP.register");
+			//
+			// remember this Admin Console for future updates
+			//
+			if ( ! adminConsoleURLStringList.contains(acURLString)) {
+				adminConsoleURLStringList.add(acURLString);
+			}
+			if (logger.isDebugEnabled()) {
+				logger.debug("Admin Console registering with URL: " + acURLString);
+			}
+			response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+			loggingContext.transactionEnded();
+			auditLogger.info("Success");
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+		}
+
+		/*
+		 * This is to update the PDP Group with the policy/policies being pushed
+		 * Part of a 2 step process to push policie to the PDP that can now be done 
+		 * From both the Admin Console and the PolicyEngine API
+		 */
+		String groupId = request.getParameter("groupId");
+		if (groupId != null) {
+			if(apiflag!=null){
+				if(apiflag.equalsIgnoreCase("addPolicyToGroup")){
+					updateGroupsFromAPI(request, response, groupId, loggingContext);
+					loggingContext.transactionEnded();
+					PolicyLogger.audit("Transaction Ended Successfully");
+					im.endTransaction();
+					return;
+				}
+			}
+			//
+			// this is from the Admin Console, so handle separately
+			//
+			doACPut(request, response, groupId, loggingContext);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+		}
+
+		//
+		// Request is for policy validation and creation
+		//
+		if (apiflag != null && apiflag.equalsIgnoreCase("admin")){
+			/*
+			 * this request is from the Admin Console
+			 */
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			doACPolicyPut(request, response);
+			im.endTransaction();
+			return;
+
+		} else if (apiflag != null && apiflag.equalsIgnoreCase("api")) {
+			/*
+			 * this request is from the Policy Creation API
+			 */
+			// Authenticating the Request here. 
+			if(authorizeRequest(request)){
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Ended Successfully");
+				doPolicyAPIPut(request, response);
+				im.endTransaction();
+				return;
+			} else {
+				String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+				PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+				im.endTransaction();
+				return;
+			}
+
+		}
+
+
+		//
+		// We do not expect anything from anywhere else.
+		// This method is here in case we ever need to support other operations.
+		//
+		logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Request does not have groupId or apiflag");
+		loggingContext.transactionEnded();
+
+		PolicyLogger.audit("Transaction Failed - See Error.log");
+		response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId or apiflag");
+		loggingContext.transactionEnded();
+		PolicyLogger.audit("Transaction Failed - See error.log");
+		im.endTransaction();
+	}
+
+	/**
+	 * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response)
+	 */
+	protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		ECOMPLoggingContext loggingContext = ECOMPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext);
+		loggingContext.transactionStarted();
+		loggingContext.setServiceName("PAP.delete"); // we may set a more specific value later
+		if ((loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")){
+			UUID requestID = UUID.randomUUID();
+			loggingContext.setRequestID(requestID.toString());
+			PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doDelete) so we generated one");
+		} else {
+			PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doDelete)");
+		}
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 1 of 2");
+		loggingContext.metricStarted();
+		loggingContext.metricEnded();
+		PolicyLogger.metrics("Metric example posted here - 2 of 2");	
+
+		//This im.startTransaction() covers all Delete transactions
+		try {
+			im.startTransaction();
+		} catch (AdministrativeStateException ae){
+			String message = "DELETE interface called for PAP " + papResourceName + " but it has an Administrative"
+					+ " state of " + im.getStateManager().getAdminState()
+					+ "\n Exception Message: " + ae.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}catch (StandbyStatusException se) {
+			se.printStackTrace();
+			String message = "PUT interface called for PAP " + papResourceName + " but it has a Standby Status"
+					+ " of " + im.getStateManager().getStandbyStatus()
+					+ "\n Exception Message: " + se.getMessage();
+			logger.info(message);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
+		}
+
+		XACMLRest.dumpRequest(request);
+
+		String groupId = request.getParameter("groupId");
+		String apiflag = request.getParameter("apiflag");
+
+		if (groupId != null) {
+			// Is this from the Admin Console or API?
+			if(apiflag!=null) {
+				if (apiflag.equalsIgnoreCase("deletePapApi")) {
+					// this is from the API so we need to check the client credentials before processing the request
+					if(authorizeRequest(request)){
+						doAPIDeleteFromPAP(request, response, loggingContext);
+						return;
+					} else {
+						String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+						PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+						return;
+					}
+				} else if (apiflag.equalsIgnoreCase("deletePdpApi")) {
+					if(authorizeRequest(request)){
+						doAPIDeleteFromPDP(request, response, loggingContext);
+						return;
+					} else {
+						String message = "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
+						PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message);
+						loggingContext.transactionEnded();
+
+						PolicyLogger.audit("Transaction Failed - See Error.log");
+						response.sendError(HttpServletResponse.SC_FORBIDDEN, message);
+						return;
+					}
+				}
+			}
+
+			// this is from the Admin Console, so handle separately
+			doACDelete(request, response, groupId, loggingContext);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Ended Successfully");
+			im.endTransaction();
+			return;
+
+		}
+		//
+		// We do not expect anything from anywhere else.
+		// This method is here in case we ever need to support other operations.
+		//
+		PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Request does not have groupId");
+		loggingContext.transactionEnded();
+
+		PolicyLogger.audit("Transaction Failed - See Error.log");
+
+		response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Request does not have groupId");
+
+		//Catch anything that fell through
+		im.endTransaction();
+
+	}
+	//
+	// Admin Console request handling
+	//
+
+	/**
+	 * Requests from the Admin Console to GET info about the Groups and PDPs
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+		try {
+			String parameterDefault = request.getParameter("default");
+			String pdpId = request.getParameter("pdpId");
+			String pdpGroup = request.getParameter("getPDPGroup");
+			if ("".equals(groupId)) {
+				// request IS from AC but does not identify a group by name
+				if (parameterDefault != null) {
+					// Request is for the Default group (whatever its id)
+					loggingContext.setServiceName("AC:PAP.getDefaultGroup");
+
+					EcompPDPGroup group = papEngine.getDefaultGroup();
+
+					// convert response object to JSON and include in the response
+					ObjectMapper mapper = new ObjectMapper();
+					mapper.writeValue(response.getOutputStream(),  group);
+
+					if (logger.isDebugEnabled()) {
+						logger.debug("GET Default group req from '" + request.getRequestURL() + "'");
+					}
+					response.setStatus(HttpServletResponse.SC_OK);
+					response.setHeader("content-type", "application/json");
+					response.getOutputStream().close();
+					loggingContext.transactionEnded();
+					auditLogger.info("Success");
+					PolicyLogger.audit("Transaction Ended Successfully");
+					return;
+
+				} else if (pdpId != null) {
+					// Request is related to a PDP
+					if (pdpGroup == null) {
+						// Request is for the PDP itself
+						// Request is for the (unspecified) group containing a given PDP
+						loggingContext.setServiceName("AC:PAP.getPDP");
+						EcompPDP pdp = papEngine.getPDP(pdpId);
+
+						// convert response object to JSON and include in the response
+						ObjectMapper mapper = new ObjectMapper();
+						mapper.writeValue(response.getOutputStream(),  pdp);
+
+						if (logger.isDebugEnabled()) {
+							logger.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
+						}
+						response.setStatus(HttpServletResponse.SC_OK);
+						response.setHeader("content-type", "application/json");
+						response.getOutputStream().close();
+						loggingContext.transactionEnded();
+						auditLogger.info("Success");
+						PolicyLogger.audit("Transaction Ended Successfully");
+						return;
+
+					} else {
+						// Request is for the group containing a given PDP
+						loggingContext.setServiceName("AC:PAP.getGroupForPDP");
+						EcompPDP pdp = papEngine.getPDP(pdpId);
+						EcompPDPGroup group = papEngine.getPDPGroup((EcompPDP) pdp);
+
+						// convert response object to JSON and include in the response
+						ObjectMapper mapper = new ObjectMapper();
+						mapper.writeValue(response.getOutputStream(),  group);
+
+						if (logger.isDebugEnabled()) {
+							logger.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
+						}
+						response.setStatus(HttpServletResponse.SC_OK);
+						response.setHeader("content-type", "application/json");
+						response.getOutputStream().close();
+						loggingContext.transactionEnded();
+						auditLogger.info("Success");
+						PolicyLogger.audit("Transaction Ended Successfully");
+						return;
+					}
+
+				} else {
+					// request is for top-level properties about all groups
+					loggingContext.setServiceName("AC:PAP.getAllGroups");
+					Set<EcompPDPGroup> groups = papEngine.getEcompPDPGroups();
+
+					// convert response object to JSON and include in the response
+					ObjectMapper mapper = new ObjectMapper();
+					mapper.writeValue(response.getOutputStream(),  groups);
+
+					if (logger.isDebugEnabled()) {
+						logger.debug("GET All groups req");
+					}
+					response.setStatus(HttpServletResponse.SC_OK);
+					response.setHeader("content-type", "application/json");
+					response.getOutputStream().close();
+					loggingContext.transactionEnded();
+					auditLogger.info("Success");
+					PolicyLogger.audit("Transaction Ended Successfully");
+					return;
+				}
+			}
+
+			// for all other GET operations the group must exist before the operation can be done
+			EcompPDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				String message = "Unknown groupId '" + groupId + "'";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				return;
+			}
+
+
+			// Figure out which request this is based on the parameters
+			String policyId = request.getParameter("policyId");
+
+			if (policyId != null) {
+				// retrieve a policy
+				loggingContext.setServiceName("AC:PAP.getPolicy");
+				//
+				// convert response object to JSON and include in the response
+				//
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
+
+			} else {
+				// No other parameters, so return the identified Group
+				loggingContext.setServiceName("AC:PAP.getGroup");
+
+				// convert response object to JSON and include in the response
+				ObjectMapper mapper = new ObjectMapper();
+				mapper.writeValue(response.getOutputStream(),  group);
+
+				if (logger.isDebugEnabled()) {
+					logger.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
+				}
+				response.setStatus(HttpServletResponse.SC_OK);
+				response.setHeader("content-type", "application/json");
+				response.getOutputStream().close();
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			}
+
+			//
+			// Currently there are no other GET calls from the AC.
+			// The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other GETs without calling the PAP.
+			// Other GETs that could be called:
+			//				Specific Group	(groupId=<groupId>)
+			//				A Policy		(groupId=<groupId> policyId=<policyId>)
+			//				A PDP			(groupId=<groupId> pdpId=<pdpId>)
+
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+		} catch (PAPException e) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(500, e.getMessage());
+			return;
+		}
+
+	}
+
+	/**
+	 * Requests from the Admin Console for validating and creating policies
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @throws JsonMappingException 
+	 * @throws JsonParseException 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doACPolicyPut(HttpServletRequest request,
+			HttpServletResponse response) throws JsonParseException, JsonMappingException, IOException {
+
+		String operation = request.getParameter("operation");
+		String policyType = request.getParameter("policyType");
+		String apiflag = request.getParameter("apiflag"); 
+
+		if ( policyType != null ) {
+			PolicyRestAdapter policyAdapter = new PolicyRestAdapter();
+			Policy newPolicy = null;
+			// get the request content into a String
+			String json = null;
+			// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+			java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+			scanner.useDelimiter("\\A");
+			json =  scanner.hasNext() ? scanner.next() : "";
+			scanner.close();
+			logger.info("JSON request from AC: " + json);
+			// convert Object sent as JSON into local object
+			ObjectMapper mapper = new ObjectMapper();
+			Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class);
+
+			StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON;
+
+			//Set policyAdapter values including parentPath (Common to all policy types)
+			//Set values for policy adapter
+			try {
+				if (operation.equalsIgnoreCase("validate")) {
+					policyAdapter.setPolicyName(policy.getPolicyName());
+					policyAdapter.setConfigType(policy.getConfigType());
+					policyAdapter.setConfigBodyData(policy.getConfigBodyData());
+				} else {
+					policyAdapter = setDataToPolicyAdapter(policy, policyType, apiflag);
+				}
+			} catch (Exception e1) {
+				logger.error("Exception occured While Setting Values for Policy Adapter"+e1);
+			}
+			// Calling Component class per policy type
+			if (policyType.equalsIgnoreCase("Config")) {
+				String configPolicyType = policy.getConfigPolicyType();
+				if (configPolicyType != null && configPolicyType.equalsIgnoreCase("Firewall Config")) {
+					newPolicy = new FirewallConfigPolicy(policyAdapter);
+				} 
+				else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("BRMS_Raw")) {
+					newPolicy = new CreateBrmsRawPolicy(policyAdapter);
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("BRMS_Param")) {
+					policyAdapter.setBrmsParamBody(policy.getDrlRuleAndUIParams());
+					newPolicy = new CreateBrmsParamPolicy(policyAdapter);
+				}
+				else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("Base")) {
+					newPolicy =  new ConfigPolicy(policyAdapter);
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("ClosedLoop_Fault")) {
+					newPolicy = new ClosedLoopPolicy(policyAdapter);
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("ClosedLoop_PM")) {
+					newPolicy = new CreateClosedLoopPerformanceMetrics(policyAdapter);	
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("DCAE Micro Service")) {	
+					newPolicy = new MicroServiceConfigPolicy(policyAdapter);
+				}
+
+			} else if (policyType.equalsIgnoreCase("Action")) {
+				newPolicy = new ActionPolicy(policyAdapter);
+			} else if (policyType.equalsIgnoreCase("Decision")) {
+				newPolicy = new DecisionPolicy(policyAdapter);	
+			}
+
+			// Validation
+			if (operation != null && operation.equalsIgnoreCase("validate")) {
+
+				// validate the body data if applicable and return a response to the PAP-ADMIN	(Config Base only)
+				if (newPolicy.validateConfigForm()) {					
+					response.setStatus(HttpServletResponse.SC_OK);
+					response.addHeader("isValidData", "true");					
+				} else {	
+					response.setStatus(HttpServletResponse.SC_OK);	
+					response.addHeader("isValidData", "false");
+				}
+
+			}   
+
+			// Create or Update Policy        
+			if (operation != null && (operation.equalsIgnoreCase("create") || operation.equalsIgnoreCase("update"))) {
+
+				// create the policy and return a response to the PAP-ADMIN		        
+				PolicyDBDaoTransaction policyDBDaoTransaction = policyDBDao.getNewTransaction();
+				try {
+					Map<String, String> successMap;
+					newPolicy.prepareToSave();
+					policyDBDaoTransaction.createPolicy(newPolicy, "doACPolicyPut");
+					successMap = newPolicy.savePolicies();
+					if (successMap.containsKey("success")) {
+						policyDBDaoTransaction.commitTransaction();
+						response.setStatus(HttpServletResponse.SC_OK);
+						response.addHeader("successMapKey", "success");		    						    				
+						response.addHeader("finalPolicyPath", policyAdapter.getFinalPolicyPath());	
+					} else {								
+						policyDBDaoTransaction.rollbackTransaction();
+						response.setStatus(HttpServletResponse.SC_OK);								
+					}	
+				} catch (Exception e) {	
+					policyDBDaoTransaction.rollbackTransaction();
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Could not save policy ");
+					response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+				}		        	
+			}
+
+		}
+
+	}
+
+	private void doPolicyAPIPut(HttpServletRequest request,
+			HttpServletResponse response) throws IOException, ServletException {
+		String operation = request.getParameter("operation");
+		String policyType = request.getParameter("policyType");
+		String apiflag = request.getParameter("apiflag");
+
+		
+		if ( policyType != null ) {
+			PolicyRestAdapter policyAdapter = new PolicyRestAdapter();
+			Policy newPolicy = null;
+
+			// get the request content into a String
+			String json = null;
+
+			// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+			java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+			scanner.useDelimiter("\\A");
+			json =  scanner.hasNext() ? scanner.next() : "";
+			scanner.close();
+			logger.info("JSON request from API: " + json);
+
+			// convert Object sent as JSON into local object
+			ObjectMapper mapper = new ObjectMapper();
+
+			Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class);
+
+			StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON;
+
+			//Set policyAdapter values including parentPath (Common to all policy types)
+			try {
+				policyAdapter = setDataToPolicyAdapter(policy, policyType, apiflag);
+			} catch (Exception e1) {
+				logger.error(XACMLErrorConstants.ERROR_UNKNOWN + 
+						"Could not set data to policy adapter ",e1);
+			}
+
+			// Calling Component class per policy type
+			if (policyType.equalsIgnoreCase("Config")) {
+				String configPolicyType = policy.getConfigPolicyType();
+				if (configPolicyType != null && configPolicyType.equalsIgnoreCase("Firewall Config")) {
+
+					newPolicy = new FirewallConfigPolicy(policyAdapter);
+
+				} 
+				else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("BRMS_Raw")) { 
+
+					newPolicy = new CreateBrmsRawPolicy(policyAdapter);
+
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("BRMS_Param")) {
+
+					policyAdapter.setBrmsParamBody(policy.getDrlRuleAndUIParams());
+					//check for valid actionAttributes
+					//Setup EntityManager to communicate with the PolicyVersion table of the DB
+					EntityManager em = null;
+					em = (EntityManager) emf.createEntityManager();
+
+					Map<String,String> ruleAndUIValue=policyAdapter.getBrmsParamBody();
+					String modelName= ruleAndUIValue.get("templateName");
+					logger.info("Template name from API is: "+modelName);
+
+					Query getModel = em.createNamedQuery("BRMSParamTemplate.findAll");	
+					List<?> modelList = getModel.getResultList(); 	
+					Boolean isValidService = false;
+					for (Object id : modelList) {
+						BRMSParamTemplate value = (BRMSParamTemplate)id;
+						logger.info("Template value from dictionary is: "+value);
+						if (modelName.equals(value.getRuleName())) {
+							isValidService = true;
+							break;
+						}
+					}
+
+					em.close();
+
+					if (isValidService) {
+						newPolicy = new CreateBrmsParamPolicy(policyAdapter);
+					} else {
+						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " 
+								+ modelName 
+								+ " was not found in the dictionary.");
+						response.addHeader("error", "missingTemplate");	
+						response.addHeader("modelName", modelName);
+						response.setStatus(HttpServletResponse.SC_BAD_REQUEST);								
+						return;
+					}
+				}
+				else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("Base")) {
+
+					newPolicy =  new ConfigPolicy(policyAdapter);
+
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("ClosedLoop_Fault")) {
+
+					newPolicy = new ClosedLoopPolicy(policyAdapter);
+
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("ClosedLoop_PM")) {
+
+					newPolicy = new CreateClosedLoopPerformanceMetrics(policyAdapter);
+
+				}else if (configPolicyType != null && configPolicyType.equalsIgnoreCase("DCAE Micro Service")) {
+
+					//check for valid actionAttributes
+					//Setup EntityManager to communicate with the PolicyVersion table of the DB
+					EntityManager em = null;
+					em = (EntityManager) emf.createEntityManager();
+
+					String modelName = policy.getServiceType();
+					String modelVersion = policy.getVersion();
+
+					Query getModel = em.createNamedQuery("MicroServiceModels.findAll");	
+					List<?> modelList = getModel.getResultList(); 	
+					Boolean isValidService = false;
+					for (Object id : modelList) {
+						MicroServiceModels value = (MicroServiceModels)id;
+						if (modelName.equals(value.getModelName()) && modelVersion.equals(value.getVersion())) {
+							isValidService = true;
+							break;
+						}
+					}
+
+					em.close();
+
+					if (isValidService) {
+						newPolicy = new MicroServiceConfigPolicy(policyAdapter);
+					} else {
+						logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Service or Version.  The Service Model, " 
+								+ modelName + " of version " + modelVersion 
+								+ " was not found in the dictionary.");
+						response.addHeader("error", "serviceModelDB");	
+						response.addHeader("modelName", modelName);
+						response.addHeader("modelVersion", modelVersion);
+						response.setStatus(HttpServletResponse.SC_BAD_REQUEST);								
+						return;
+					}
+
+				}
+
+			} else if (policyType.equalsIgnoreCase("Action")) {
+
+				//check for valid actionAttributes
+				//Setup EntityManager to communicate with the PolicyVersion table of the DB
+				EntityManager em = null;
+				em = (EntityManager) emf.createEntityManager();
+
+				String attributeName = policy.getActionAttribute();
+
+				Query getActionAttributes = em.createNamedQuery("ActionPolicyDict.findAll");	
+				List<?> actionAttributesList = getActionAttributes.getResultList(); 	
+				Boolean isAttribute = false;
+				for (Object id : actionAttributesList) {
+					ActionPolicyDict value = (ActionPolicyDict)id;
+					if (attributeName.equals(value.getAttributeName())) {
+						isAttribute = true;
+						break;
+					}
+				}
+
+				em.close();
+
+				if (isAttribute) {
+					newPolicy = new ActionPolicy(policyAdapter);
+				} else {
+					logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not fine " + attributeName + " in the ActionPolicyDict table.");
+					response.addHeader("error", "actionPolicyDB");	
+					response.addHeader("actionAttribute", attributeName);
+					response.setStatus(HttpServletResponse.SC_BAD_REQUEST);								
+					return;
+				}
+
+			} else if (policyType.equalsIgnoreCase("Decision")) {
+
+				newPolicy = new DecisionPolicy(policyAdapter);
+
+			}
+
+			// Create or Update Policy        
+			if (operation != null && (operation.equalsIgnoreCase("create") || operation.equalsIgnoreCase("update"))) {
+
+				// create the policy and return a response to the PAP-ADMIN		        
+				if (newPolicy.validateConfigForm()) {		        		
+					PolicyDBDaoTransaction policyDBDaoTransaction = policyDBDao.getNewTransaction();
+					try {	
+
+						// added check for existing policy when new policy is created to 
+						// unique API error for "policy already exists" 
+						Boolean isNewPolicy = newPolicy.prepareToSave();
+						if(isNewPolicy){
+							policyDBDaoTransaction.createPolicy(newPolicy, "doPolicyAPIPut");
+						}
+						Map<String, String> successMap = newPolicy.savePolicies();							
+						if (successMap.containsKey("success")) {
+							
+							EntityManager apiEm = null;
+							apiEm = (EntityManager) emf.createEntityManager();
+							//
+							// Did it get created?
+							//
+							if (apiEm == null) {
+								PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE +  " Error creating entity manager with persistence unit: " + PERSISTENCE_UNIT);	
+								ServletException e = new ServletException("Unable to create Entity Manager Factory");
+								e.printStackTrace();
+								throw e;
+							}
+							
+							String finalPath = policyAdapter.getFinalPolicyPath();
+		    				//
+		    				//Check the database entry if a scope is available in PolicyEditorScope table or not.
+		    				//If not exists create a new entry.
+		    				//
+		    				String dirName = finalPath.toString().substring(finalPath.toString().indexOf("repository")+11, finalPath.toString().lastIndexOf(File.separator));
+		    				apiEm.getTransaction().begin();
+		    				Query query = apiEm.createQuery("Select p from PolicyEditorScopes p where p.scopeName=:sname");
+		    				query.setParameter("sname", dirName);
+		    				
+		    				@SuppressWarnings("rawtypes")
+		    				List result = query.getResultList();
+		    				if(result.isEmpty()){
+		    					PolicyEditorScopes scopeEntity = new PolicyEditorScopes();
+		    					scopeEntity.setScopeName(dirName);
+		    					UserInfo user = new UserInfo();
+		    					user.setUserLoginId("API");
+		    					user.setUserName("API");
+		    					scopeEntity.setUserCreatedBy(user);
+		    					scopeEntity.setUserModifiedBy(user);
+		    					try{
+		    						apiEm.persist(scopeEntity);
+			    					apiEm.getTransaction().commit();
+		    					}catch(Exception e){
+		    						PolicyLogger.error("Exception Occured while inserting a new Entry to PolicyEditorScopes table"+e);
+		    						apiEm.getTransaction().rollback();
+		    					}finally{
+		    						apiEm.close();
+		    					}
+		    				}else{
+	    						PolicyLogger.info("Scope Already Exists in PolicyEditorScopes table, Hence Closing the Transaction");
+	    						apiEm.close();
+	    					}
+		    				
+							policyDBDaoTransaction.commitTransaction();
+							response.setStatus(HttpServletResponse.SC_OK);								
+							response.addHeader("successMapKey", "success");								
+							response.addHeader("policyName", policyAdapter.getPolicyName());
+
+							if (operation.equalsIgnoreCase("update")) {
+								response.addHeader("operation",  "update");
+							} else {
+								response.addHeader("operation", "create");
+							}
+						} else if (successMap.containsKey("EXISTS")) {
+							policyDBDaoTransaction.rollbackTransaction();
+							response.setStatus(HttpServletResponse.SC_CONFLICT);
+							response.addHeader("error", "policyExists");
+							response.addHeader("policyName", policyAdapter.getPolicyName());
+						} else if (successMap.containsKey("fwdberror")) {
+							policyDBDaoTransaction.rollbackTransaction();
+							response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+							response.addHeader("error", "FWDBError");
+							response.addHeader("policyName", policyAdapter.getPolicyName());
+						}else {						
+							policyDBDaoTransaction.rollbackTransaction();
+							response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);								
+							response.addHeader("error", "error");							
+						}						
+					} catch (Exception e) {							
+						policyDBDaoTransaction.rollbackTransaction();
+						String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + 
+								"Could not save policy " + e;
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Could not save policy");
+						response.setStatus(HttpServletResponse.SC_BAD_REQUEST);	
+						response.addHeader("error", "savePolicy");
+						response.addHeader("message", message);
+					}		        	
+				}
+			}
+		}
+	}
+
+	private PolicyRestAdapter setDataToPolicyAdapter(StdPAPPolicy policy, String policyType, String apiflag) throws Exception {
+		PolicyRestAdapter policyAdapter = new PolicyRestAdapter();
+		int highestVersion = 0;
+
+		if (policy.getHighestVersion()!=null) {	
+			highestVersion = policy.getHighestVersion();
+		}
+
+		EntityManager apiEm = null;
+		apiEm = (EntityManager) emf.createEntityManager();
+
+		//
+		// Did it get created?
+		//
+		if (apiEm == null) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + 
+					" Error creating entity manager with persistence unit: "
+					+ PERSISTENCE_UNIT);	
+			throw new ServletException("Unable to create Entity Manager Factory");
+		}
+
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+
+		/*
+		 * Getting and Setting the parent path for Admin Console use when reading the policy files
+		 */
+		//domain chosen by the client to store the policy action files 
+		String domain = policy.getDomainDir();
+
+		//adding the domain to the gitPath
+		Path path;
+		String gitPathString = gitPath.toString();
+
+		if (gitPathString.contains("\\")) {
+			path = Paths.get(gitPath + "\\" + policy.getDomainDir());
+		} else {
+			path = Paths.get(gitPath + "/" + policy.getDomainDir());
+
+		}
+		logger.debug("path is: " + path.toString());
+
+		//getting the fullpath of the gitPath and convert to string
+		String policyDir = path.toAbsolutePath().toString();
+		String parentPath = null;
+
+		//creating the parentPath directory for the Admin Console use
+		File file;
+		if(policyDir.contains("\\"))
+		{
+			parentPath = policyDir.replace("ECOMP-PAP-REST", "ecomp-sdk-app");
+			file = new File(parentPath);
+		}
+		else
+		{
+			parentPath = policyDir.replace("pap",  "console");
+			file = new File(parentPath);
+
+		}
+
+		//Get the policy file from the git repository
+		String filePrefix = null;
+		if (policyType.equalsIgnoreCase("Config")) {
+			if (policy.getConfigPolicyType().equalsIgnoreCase("Firewall Config")) {
+				filePrefix = "Config_FW_";
+			}else if (policy.getConfigPolicyType().equalsIgnoreCase("ClosedLoop_Fault")) {
+				filePrefix = "Config_Fault_";
+			}else if (policy.getConfigPolicyType().equalsIgnoreCase("ClosedLoop_PM")) {
+				filePrefix = "Config_PM_";
+			}else if (policy.getConfigPolicyType().equalsIgnoreCase("DCAE Micro Service")) {
+				filePrefix = "Config_MS_";
+			} else if (policy.getConfigPolicyType().equalsIgnoreCase("BRMS_Raw")) {
+				filePrefix = "Config_BRMS_Raw_";
+			} else if (policy.getConfigPolicyType().equalsIgnoreCase("BRMS_Param")) {
+				filePrefix = "Config_BRMS_Param_";
+			}
+			else {
+				filePrefix = "Config_";
+			}
+		} else if (policyType.equalsIgnoreCase("Action")) {
+			filePrefix = "Action_";
+		} else if (policyType.equalsIgnoreCase("Decision")) {
+			filePrefix = "Decision_";
+		}
+
+
+		String pvName = domain + File.separator + filePrefix + policy.getPolicyName();
+
+		//create the directory if it does not exist
+		Boolean fileDir=true;
+		if (!file.exists()){
+			fileDir = new File(parentPath).mkdirs();
+		}
+
+		//set the parent path in the policy adapter
+		if (!fileDir){
+			logger.debug("Unable to create the policy directory");
+		}
+
+		logger.debug("ParentPath is: " + parentPath.toString());
+		policyAdapter.setParentPath(parentPath.toString());
+		policyAdapter.setApiflag(apiflag);
+
+		if (policy.isEditPolicy()) {
+
+			if(apiflag.equalsIgnoreCase("api")) {
+
+				//Get the Highest Version to Update
+				apiEm.getTransaction().begin();
+				Query query = apiEm.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
+				query.setParameter("pname", pvName);
+
+				@SuppressWarnings("rawtypes")
+				List result = query.getResultList();
+				PolicyVersion versionEntity = null;
+				if (!result.isEmpty()) {
+					versionEntity = (PolicyVersion) result.get(0);
+					apiEm.persist(versionEntity);
+					highestVersion = versionEntity.getHigherVersion();
+					int activeVersion = versionEntity.getActiveVersion();
+
+					Calendar calendar = Calendar.getInstance();
+					Timestamp modifyDate = new Timestamp(calendar.getTime().getTime());
+
+					//update table with highestVersion
+					try{
+						versionEntity.setHigherVersion(highestVersion+1);
+						versionEntity.setActiveVersion(activeVersion+1);
+						versionEntity.setCreatedBy("API");
+						versionEntity.setModifiedBy("API");
+						versionEntity.setModifiedDate(modifyDate);
+
+						apiEm.getTransaction().commit();
+
+					}catch(Exception e){
+						apiEm.getTransaction().rollback();
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
+					} finally {
+						apiEm.close();
+					}
+				} else {
+					logger.debug("\nNo PolicyVersion using policyName found");
+				}		
+
+			}
+
+			File policyFile = null;
+			if(policy.getOldPolicyFileName() != null && policy.getOldPolicyFileName().endsWith("Draft.1")) {
+				policyFile = new File(parentPath.toString() + File.separator + policy.getOldPolicyFileName() + ".xml");
+			} else {
+				policyFile = new File(parentPath.toString() + File.separator + filePrefix + policy.getPolicyName() +"."+(highestVersion)+ ".xml");
+			}
+
+			if (policyFile.exists()) {
+				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+				Document doc = dBuilder.parse(policyFile);
+
+				doc.getDocumentElement().normalize();
+
+				String version = doc.getDocumentElement().getAttribute("Version");
+
+				NodeList rList = doc.getElementsByTagName("Rule");
+				Node rNode = rList.item(0);
+				Element rElement = (Element) rNode;
+
+				String ruleID = null;
+				if (rNode!=null){
+					ruleID = rElement.getAttribute("RuleId");
+				} else {
+					ruleID = newRuleID();
+				}
+
+				policyAdapter.setPolicyID(newPolicyID());
+				policyAdapter.setRuleID(ruleID);
+				policyAdapter.setVersion(version);
+
+			} else {
+				PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " The policy file at the path " + policyFile + " does not exist.");
+			}
+
+		} else {
+
+			highestVersion = 1;
+			if (apiflag.equalsIgnoreCase("api")) {
+				Calendar calendar = Calendar.getInstance();
+				Timestamp createdDate = new Timestamp(calendar.getTime().getTime());
+
+				apiEm.getTransaction().begin();
+				Query query = apiEm.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
+				query.setParameter("pname", pvName);
+
+				@SuppressWarnings("rawtypes")
+				List result = query.getResultList();
+
+				if (result.isEmpty()) {
+
+					try{
+						PolicyVersion versionEntity = new PolicyVersion();
+						apiEm.persist(versionEntity);
+						versionEntity.setPolicyName(pvName);
+						versionEntity.setHigherVersion(highestVersion);
+						versionEntity.setActiveVersion(highestVersion);
+						versionEntity.setCreatedBy("API");
+						versionEntity.setModifiedBy("API");
+						versionEntity.setCreatedDate(createdDate);
+						versionEntity.setModifiedDate(createdDate);
+
+						apiEm.getTransaction().commit();
+
+					}catch(Exception e){
+						apiEm.getTransaction().rollback();
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
+					} finally {
+						apiEm.close();
+					}		
+				}
+			}
+
+			policyAdapter.setPolicyID(newPolicyID());
+			policyAdapter.setRuleID(newRuleID());	
+
+		}
+
+		/*
+		 * set policy adapter values for Building JSON object containing policy data
+		 */
+		//Common among policy types
+		policyAdapter.setPolicyName(policy.getPolicyName());
+		policyAdapter.setPolicyDescription(policy.getPolicyDescription());
+		policyAdapter.setEcompName(policy.getEcompName()); //Config Base and Decision Policies
+		policyAdapter.setHighestVersion(highestVersion);
+		policyAdapter.setRuleCombiningAlgId("urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides");
+		policyAdapter.setUserGitPath(gitPath.toString());
+		policyAdapter.setPolicyType(policyType);
+		policyAdapter.setDynamicFieldConfigAttributes(policy.getDynamicFieldConfigAttributes());
+		policyAdapter.setEditPolicy(policy.isEditPolicy());
+		policyAdapter.setEntityManagerFactory(getEmf());
+
+
+		//Config Specific
+		policyAdapter.setConfigName(policy.getConfigName());  //Base and Firewall
+		policyAdapter.setConfigBodyData(policy.getConfigBodyData()); //Base
+		policyAdapter.setConfigType(policy.getConfigType());  //Base
+		policyAdapter.setJsonBody(policy.getJsonBody()); //Firewall, ClosedLoop, and GoC
+		policyAdapter.setConfigPolicyType(policy.getConfigPolicyType());
+		policyAdapter.setDraft(policy.isDraft()); //ClosedLoop_Fault
+		policyAdapter.setServiceType(policy.getServiceType()); //ClosedLoop_PM
+		policyAdapter.setUuid(policy.getUuid()); //Micro Service
+		policyAdapter.setLocation(policy.getMsLocation()); //Micro Service
+		policyAdapter.setPriority(policy.getPriority()); //Micro Service
+		policyAdapter.setPolicyScope(policy.getDomainDir());
+		policyAdapter.setRiskType(policy.getRiskType()); //Safe Policy Attributes
+		policyAdapter.setRiskLevel(policy.getRiskLevel());//Safe Policy Attributes
+		policyAdapter.setGuard(policy.getGuard());//Safe Policy Attributes
+		policyAdapter.setTtlDate(policy.getTTLDate());//Safe Policy Attributes
+
+		//Action Policy Specific
+		policyAdapter.setActionAttribute(policy.getActionAttribute());  //comboDictValue
+		policyAdapter.setActionPerformer(policy.getActionPerformer());
+		policyAdapter.setDynamicRuleAlgorithmLabels(policy.getDynamicRuleAlgorithmLabels());
+		policyAdapter.setDynamicRuleAlgorithmCombo(policy.getDynamicRuleAlgorithmCombo());
+		policyAdapter.setDynamicRuleAlgorithmField1(policy.getDynamicRuleAlgorithmField1());
+		policyAdapter.setDynamicRuleAlgorithmField2(policy.getDynamicRuleAlgorithmField2());
+
+		//Decision Policy Specific
+		policyAdapter.setDynamicSettingsMap(policy.getDynamicSettingsMap());
+		policyAdapter.setProviderComboBox(policy.getProviderComboBox());
+
+		return policyAdapter;
+	}
+
+	public String	newPolicyID() {
+		return Joiner.on(':').skipNulls().join((XACMLPapServlet.getDomain().startsWith("urn") ? null : "urn"),
+				XACMLPapServlet.getDomain().replaceAll("[/\\\\.]", ":"), 
+				"xacml", "policy", "id", UUID.randomUUID());
+	}
+
+	public String	newRuleID() {
+		return Joiner.on(':').skipNulls().join((XACMLPapServlet.getDomain().startsWith("urn") ? null : "urn"),
+				XACMLPapServlet.getDomain().replaceAll("[/\\\\.]", ":"), 
+				"xacml", "rule", "id", UUID.randomUUID());
+	}
+
+	public static String	getDomain() {
+		return XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DOMAIN, "urn");
+	}
+
+
+	/**
+	 * Requests from the Admin Console for operations not on single specific objects
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+		PolicyDBDaoTransaction doACPostTransaction = null;
+
+		try {
+			String groupName = request.getParameter("groupName");
+			String groupDescription = request.getParameter("groupDescription");
+			String apiflag = request.getParameter("apiflag");
+
+			if (groupName != null && groupDescription != null) {
+				// Args:	      group=<groupId> groupName=<name> groupDescription=<description>            <= create a new group
+				loggingContext.setServiceName("AC:PAP.createGroup");
+
+				String unescapedName = URLDecoder.decode(groupName, "UTF-8");
+				String unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
+				PolicyDBDaoTransaction newGroupTransaction = policyDBDao.getNewTransaction();
+				try {					
+					newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName, unescapedDescription,"XACMLPapServlet.doACPost");
+					papEngine.newGroup(unescapedName, unescapedDescription);
+					newGroupTransaction.commitTransaction();
+				} catch (Exception e) {
+					newGroupTransaction.rollbackTransaction();
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to create new group");
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(500, "Unable to create new group '" + groupId + "'");
+					return;
+				}
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("New Group '" + groupId + "' created");
+				}
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// new group by definition has no PDPs, so no need to notify them of changes
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			}
+
+			// for all remaining POST operations the group must exist before the operation can be done
+			EcompPDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				String message = "Unknown groupId '" + groupId + "'";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				if (apiflag!=null){
+					response.addHeader("error", "unknownGroupId");
+					response.addHeader("operation", "push");
+					response.addHeader("message", message);
+					response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+				} else {
+					response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				}
+				return;
+			}
+
+			// determine the operation needed based on the parameters in the request
+			if (request.getParameter("policyId") != null) {
+				//	Args:        group=<groupId> policy=<policyId>		<= copy file
+				// copy a policy from the request contents into a file in the group's directory on this machine
+				if(apiflag!=null){
+					loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
+				} else {
+					loggingContext.setServiceName("AC:PAP.postPolicy");
+				}
+
+				String policyId = request.getParameter("policyId");
+				PolicyDBDaoTransaction addPolicyToGroupTransaction = policyDBDao.getNewTransaction();
+				try {
+					InputStream is = null;
+					if (apiflag != null){
+						// get the request content into a String if the request is from API 
+						String json = null;
+						// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+						java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+						scanner.useDelimiter("\\A");
+						json =  scanner.hasNext() ? scanner.next() : "";
+						scanner.close();
+						logger.info("JSON request from API: " + json);
+
+						// convert Object sent as JSON into local object
+						ObjectMapper mapper = new ObjectMapper();
+
+						Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class);
+
+						StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON;
+
+						is = new FileInputStream(new File(policy.getLocation()));
+					} else {
+						is = request.getInputStream();
+
+					}
+
+					addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,"XACMLPapServlet.doACPost");
+					((StdPDPGroup) group).copyPolicyToFile(policyId, is);
+					addPolicyToGroupTransaction.commitTransaction();
+
+				} catch (Exception e) {
+					addPolicyToGroupTransaction.rollbackTransaction();
+					String message = "Policy '" + policyId + "' not copied to group '" + groupId +"': " + e;
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+
+					if (apiflag!=null){
+						response.addHeader("error", "policyCopyError");
+						response.addHeader("message", message);
+						response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+					} else {
+						response.sendError(500, message);
+					}
+					return;
+				}
+
+				// policy file copied ok and the Group was updated on the PDP
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				response.addHeader("operation", "push");
+				response.addHeader("policyId", policyId);
+				response.addHeader("groupId", groupId);
+				if (logger.isDebugEnabled()) {
+					logger.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'");
+				}
+
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+
+			} else if (request.getParameter("default") != null) {
+				// Args:       group=<groupId> default=true               <= make default
+				// change the current default group to be the one identified in the request.
+				loggingContext.setServiceName("AC:PAP.setDefaultGroup");
+				//
+				// This is a POST operation rather than a PUT "update group" because of the side-effect that the current default group is also changed.
+				// It should never be the case that multiple groups are currently marked as the default, but protect against that anyway.
+				PolicyDBDaoTransaction setDefaultGroupTransaction = policyDBDao.getNewTransaction();
+				try {
+					setDefaultGroupTransaction.changeDefaultGroup(group, "XACMLPapServlet.doACPost");
+					papEngine.SetDefaultGroup(group);
+					setDefaultGroupTransaction.commitTransaction();
+				} catch (Exception e) {
+					setDefaultGroupTransaction.rollbackTransaction();
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to set group");
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(500, "Unable to set group '" + groupId + "' to default");
+					return;
+				}
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("Group '" + groupId + "' set to be default");
+				}
+				// Notify the Admin Consoles that something changed
+				// For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+				//TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to update whole configuration of all groups
+				notifyAC();
+				// This does not affect any PDPs in the existing groups, so no need to notify them of this change
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+
+			} else if (request.getParameter("pdpId") != null) {
+				doACPostTransaction = policyDBDao.getNewTransaction();
+				// Args:       group=<groupId> pdpId=<pdpId>               <= move PDP to group
+				loggingContext.setServiceName("AC:PAP.movePDP");
+
+				String pdpId = request.getParameter("pdpId");
+				EcompPDP pdp = papEngine.getPDP(pdpId);
+
+				EcompPDPGroup originalGroup = papEngine.getPDPGroup((EcompPDP) pdp);
+				try{
+					doACPostTransaction.movePdp(pdp, group, "XACMLPapServlet.doACPost");
+				}catch(Exception e){	
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", 
+							" Error while moving pdp in the database: "
+									+"pdp="+pdp.getId()+",to group="+group.getId());
+					throw new PAPException(e.getMessage());
+				}
+				papEngine.movePDP((EcompPDP) pdp, group);
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("PDP '" + pdp.getId() +"' moved to group '" + group.getId() + "' set to be default");
+				}
+
+				// update the status of both the original group and the new one
+				((StdPDPGroup)originalGroup).resetStatus();
+				((StdPDPGroup)group).resetStatus();
+
+				// Notify the Admin Consoles that something changed
+				// For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just notify on that
+				notifyAC();
+				// Need to notify the PDP that it's config may have changed
+				pdpChanged(pdp);
+				doACPostTransaction.commitTransaction();
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+
+
+			}
+		} catch (PAPException e) {
+			if(doACPostTransaction != null){
+				doACPostTransaction.rollbackTransaction();
+			}
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC POST exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	/**
+	 * Requests from the Admin Console to create new items or update existing ones
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+		PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
+		try {
+
+
+			// for PUT operations the group may or may not need to exist before the operation can be done
+			EcompPDPGroup group = papEngine.getGroup(groupId);
+
+			// determine the operation needed based on the parameters in the request
+
+			// for remaining operations the group must exist before the operation can be done
+			if (group == null) {
+				String message = "Unknown groupId '" + groupId + "'";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+				return;
+			}
+			if (request.getParameter("policy") != null) {
+				//        group=<groupId> policy=<policyId> contents=policy file               <= Create new policy file in group dir, or replace it if it already exists (do not touch properties)
+				loggingContext.setServiceName("AC:PAP.putPolicy");
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PARTIALLY IMPLEMENTED!!!  ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			} else if (request.getParameter("pdpId") != null) {
+				// ARGS:        group=<groupId> pdpId=<pdpId/URL>          <= create a new PDP or Update an Existing one
+
+				String pdpId = request.getParameter("pdpId");
+				if (papEngine.getPDP(pdpId) == null) {
+					loggingContext.setServiceName("AC:PAP.createPDP");
+				} else {
+					loggingContext.setServiceName("AC:PAP.updatePDP");
+				}
+
+				// get the request content into a String
+				String json = null;
+				// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+				java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+				scanner.useDelimiter("\\A");
+				json =  scanner.hasNext() ? scanner.next() : "";
+				scanner.close();
+				logger.info("JSON request from AC: " + json);
+
+				// convert Object sent as JSON into local object
+				ObjectMapper mapper = new ObjectMapper();
+
+				Object objectFromJSON = mapper.readValue(json, StdPDP.class);
+
+				if (pdpId == null ||
+						objectFromJSON == null ||
+						! (objectFromJSON instanceof StdPDP) ||
+						((StdPDP)objectFromJSON).getId() == null ||
+						! ((StdPDP)objectFromJSON).getId().equals(pdpId)) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId + " objectFromJSON="+objectFromJSON);
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(500, "Bad input, pdpid="+pdpId+" object="+objectFromJSON);
+				}
+				StdPDP pdp = (StdPDP) objectFromJSON;
+
+				if (papEngine.getPDP(pdpId) == null) {
+					// this is a request to create a new PDP object
+					try{
+						acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(), pdp.getDescription(), pdp.getJmxPort(),"XACMLPapServlet.doACPut");
+					} catch(Exception e){
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while adding pdp to group in the database: "
+								+"pdp="+pdp.getId()+",to group="+group.getId());
+						throw new PAPException(e.getMessage());
+					}
+					papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
+				} else {
+					try{
+						acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
+					} catch(Exception e){
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating pdp in the database: "
+								+"pdp="+pdp.getId());
+						throw new PAPException(e.getMessage());
+					}
+					// this is a request to update the pdp
+					papEngine.updatePDP(pdp);
+				}
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("PDP '" + pdpId + "' created/updated");
+				}
+
+				// adjust the group's state including the new PDP
+				((StdPDPGroup)group).resetStatus();
+
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// this might affect the PDP, so notify it of the change
+				pdpChanged(pdp);
+				acPutTransaction.commitTransaction();
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			} else if (request.getParameter("pipId") != null) {
+				//                group=<groupId> pipId=<pipEngineId> contents=pip properties              <= add a PIP to pip config, or replace it if it already exists (lenient operation) 
+				loggingContext.setServiceName("AC:PAP.putPIP");
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else {
+				// Assume that this is an update of an existing PDP Group
+				// ARGS:        group=<groupId>         <= Update an Existing Group
+				loggingContext.setServiceName("AC:PAP.updateGroup");
+
+				// get the request content into a String
+				String json = null;
+				// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+				java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+				scanner.useDelimiter("\\A");
+				json =  scanner.hasNext() ? scanner.next() : "";
+				scanner.close();
+				logger.info("JSON request from AC: " + json);
+
+				// convert Object sent as JSON into local object
+				ObjectMapper mapper = new ObjectMapper();
+
+				Object objectFromJSON  = mapper.readValue(json, StdPDPGroup.class);
+
+				if (objectFromJSON == null ||
+						! (objectFromJSON instanceof StdPDPGroup) ||
+						! ((StdPDPGroup)objectFromJSON).getId().equals(group.getId())) {
+					PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + group.getId() + " objectFromJSON="+objectFromJSON);
+					loggingContext.transactionEnded();
+
+					PolicyLogger.audit("Transaction Failed - See Error.log");
+					response.sendError(500, "Bad input, id="+group.getId() +" object="+objectFromJSON);
+				}
+
+				// The Path on the PAP side is not carried on the RESTful interface with the AC
+				// (because it is local to the PAP)
+				// so we need to fill that in before submitting the group for update
+				((StdPDPGroup)objectFromJSON).setDirectory(((StdPDPGroup)group).getDirectory());
+
+				try{
+					acPutTransaction.updateGroup((StdPDPGroup)objectFromJSON, "XACMLPapServlet.doACPut");
+				} catch(Exception e){
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
+							+"group="+group.getId());
+					throw new PAPException(e.getMessage());
+				}
+				papEngine.updateGroup((StdPDPGroup)objectFromJSON);
+
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				if (logger.isDebugEnabled()) {
+					logger.debug("Group '" + group.getId() + "' updated");
+				}
+				acPutTransaction.commitTransaction();
+				// tell the Admin Consoles there is a change
+				notifyAC();
+				// Group changed, which might include changing the policies
+				groupChanged(group);
+
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			}
+		} catch (PAPException e) {
+			acPutTransaction.rollbackTransaction();
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC PUT exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+	/**
+	 * Requests from the Admin Console to delete/remove items
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+
+		//This is temporary code to allow deletes to propagate to the database since delete is not implemented
+		String isDeleteNotify = request.getParameter("isDeleteNotify");
+		if(isDeleteNotify != null){
+			String policyToDelete = request.getParameter("policyToDelete");
+			try{
+				policyToDelete = URLDecoder.decode(policyToDelete,"UTF-8");
+			} catch(UnsupportedEncodingException e){
+				PolicyLogger.error("Unsupported URL encoding of policyToDelete (UTF-8");
+				response.sendError(500,"policyToDelete encoding not supported");
+				return;
+			}
+			PolicyDBDaoTransaction deleteTransaction = policyDBDao.getNewTransaction();
+			try{
+				deleteTransaction.deletePolicy(policyToDelete);
+			} catch(Exception e){
+				deleteTransaction.rollbackTransaction();
+				response.sendError(500,"deleteTransaction.deleteTransaction(policyToDelete) "
+						+ "\nfailure with the following exception: " + e);
+				return;
+			}
+			deleteTransaction.commitTransaction();
+			response.setStatus(HttpServletResponse.SC_OK);
+			return;
+		}
+		PolicyDBDaoTransaction removePdpOrGroupTransaction = policyDBDao.getNewTransaction();
+		try {
+			// for all DELETE operations the group must exist before the operation can be done
+			loggingContext.setServiceName("AC:PAP.delete");
+			EcompPDPGroup group = papEngine.getGroup(groupId);
+			if (group == null) {
+				String message = "Unknown groupId '" + groupId + "'";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId +"'");
+				return;
+			}
+
+
+			// determine the operation needed based on the parameters in the request
+			if (request.getParameter("policy") != null) {
+				//        group=<groupId> policy=<policyId>  [delete=<true|false>]       <= delete policy file from group
+				loggingContext.setServiceName("AC:PAP.deletePolicy");
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
+				//DATABASE so can policies not be deleted? or doesn't matter maybe as long as this gets called
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else if (request.getParameter("pdpId") != null) {
+				// ARGS:        group=<groupId> pdpId=<pdpId>                  <= delete PDP 
+				String pdpId = request.getParameter("pdpId");
+				EcompPDP pdp = papEngine.getPDP(pdpId);
+
+				try{
+					removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(),"XACMLPapServlet.doACDelete");
+				} catch(Exception e){
+					throw new PAPException();
+				}
+				papEngine.removePDP((EcompPDP) pdp);
+
+				// adjust the status of the group, which may have changed when we removed this PDP
+				((StdPDPGroup)group).resetStatus();
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				notifyAC();
+
+				// update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests)
+				pdpChanged(pdp);
+				removePdpOrGroupTransaction.commitTransaction();
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			} else if (request.getParameter("pipId") != null) {
+				//        group=<groupId> pipId=<pipEngineId> <= delete PIP config for given engine
+
+				loggingContext.setServiceName("AC:PAP.deletePIPConfig");
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
+				loggingContext.transactionEnded();
+
+				PolicyLogger.audit("Transaction Failed - See Error.log");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
+				return;
+			} else {
+				// ARGS:      group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>            <= delete a group and move all its PDPs to the given group
+				String moveToGroupId = request.getParameter("movePDPsToGroupId");
+				EcompPDPGroup moveToGroup = null;
+				if (moveToGroupId != null) {
+					moveToGroup = papEngine.getGroup(moveToGroupId);
+				}
+
+				// get list of PDPs in the group being deleted so we can notify them that they got changed
+				Set<EcompPDP> movedPDPs = new HashSet<EcompPDP>();
+				movedPDPs.addAll(group.getEcompPdps());
+
+				// do the move/remove
+				try{
+					removePdpOrGroupTransaction.deleteGroup(group, moveToGroup,"XACMLPapServlet.doACDelete");
+				} catch(Exception e){
+					PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", " Failed to delete PDP Group. Exception");
+					e.printStackTrace();
+					throw new PAPException(e.getMessage());
+				}
+				papEngine.removeGroup(group, moveToGroup);
+
+				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+				notifyAC();
+				// notify any PDPs in the removed set that their config may have changed
+				for (EcompPDP pdp : movedPDPs) {
+					pdpChanged(pdp);
+				}
+				removePdpOrGroupTransaction.commitTransaction();
+				loggingContext.transactionEnded();
+				auditLogger.info("Success");
+				PolicyLogger.audit("Transaction Ended Successfully");
+				return;
+			}
+
+		} catch (PAPException e) {
+			removePdpOrGroupTransaction.rollbackTransaction();
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC DELETE exception");
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Exception in request processing");
+			response.sendError(500, e.getMessage());
+			return;
+		}
+	}
+
+
+	/**
+	 * Requests from the API to delete/remove items
+	 * 
+	 * @param request
+	 * @param response
+	 * @param groupId
+	 * @param loggingContext 
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+
+		// get the request content into a String
+		String json = null;
+
+		// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+		java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
+		scanner.useDelimiter("\\A");
+		json =  scanner.hasNext() ? scanner.next() : "";
+		scanner.close();
+		logger.info("JSON request from API: " + json);
+
+		// convert Object sent as JSON into local object
+		ObjectMapper mapper = new ObjectMapper();
+
+		Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class);
+
+		StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON;
+
+		String policyName = policy.getPolicyName();
+		String fileSeparator = File.separator;
+		policyName = policyName.replaceFirst("\\.", "\\"+fileSeparator);
+
+		File file = getPolicyFile(policyName);
+		String domain = getParentPathSubScopeDir(file);
+		Boolean policyFileDeleted = false;
+		Boolean configFileDeleted = false;
+		Boolean policyVersionScoreDeleted = false;
+
+		if (policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
+
+			//check for extension in policyName
+			String removexmlExtension = null;
+			String removeVersion = null;
+			if (policyName.contains("xml")) {
+				removexmlExtension = file.toString().substring(0, file.toString().lastIndexOf("."));
+				removeVersion = removexmlExtension.substring(0, removexmlExtension.lastIndexOf("."));
+			} else {
+				removeVersion = file.toString();
+			}
+
+			File dirXML = new File(file.getParent());
+			File[] listofXMLFiles = dirXML.listFiles();
+
+			for (File files : listofXMLFiles) {
+				//delete the xml files from the Repository
+				if (files.isFile() && files.toString().contains(removeVersion)) {
+					JPAUtils jpaUtils = null;
+					try {
+						jpaUtils = JPAUtils.getJPAUtilsInstance(emf);
+					} catch (Exception e) {
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP");
+						e.printStackTrace();
+						response.addHeader("error", "jpautils");
+						response.addHeader("operation", "delete");
+						response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+						return;
+					}
+
+					if (jpaUtils.dbLockdownIgnoreErrors()) {
+						logger.warn("Policies are locked down");
+						response.addHeader("operation", "delete");
+						response.addHeader("lockdown", "true");
+						response.setStatus(HttpServletResponse.SC_ACCEPTED);
+						return;
+					}
+
+					//Propagates delete to the database 
+					Boolean deletedFromDB = notifyDBofDelete(files.toString());
+
+					if (deletedFromDB) {
+						logger.info("Policy deleted from the database.  Continuing with file delete");
+					} else {
+						PolicyLogger.error("Failed to delete Policy from database. Aborting file delete");
+						response.addHeader("error", "deleteDB");
+						response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+						return;
+					}
+
+					if (files.delete()) {
+						if (logger.isDebugEnabled()) {
+							logger.debug("Deleted file: " + files.toString());
+						}
+						policyFileDeleted = true;
+					} else {
+						logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + 
+								"Cannot delete the policy file in specified location: " + files.getAbsolutePath());	
+						response.addHeader("error", "deleteFile");
+						response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+						return;
+					}
+
+					// Get tomcat home directory for deleting config data
+					logger.info("print the path:" +domain);
+					String path = domain.replace('\\', '.');
+					if(path.contains("/")){
+						path = path.replace('/', '.');
+						logger.info("print the path:" +path);
+					}
+					String fileName = FilenameUtils.removeExtension(file.getName());
+					String removeVersionInFileName = fileName.substring(0, fileName.lastIndexOf("."));
+					String fileLocation = null;
+
+					if(CONFIG_HOME == null){
+						CONFIG_HOME = getConfigHome();
+					}
+					if(ACTION_HOME == null){
+						ACTION_HOME = getActionHome();
+					}
+
+
+					if (fileName != null && fileName.contains("Config_")) {
+						fileLocation = CONFIG_HOME;
+					} else if (fileName != null && fileName.contains("Action_")) {
+						fileLocation = ACTION_HOME;
+					}
+
+					if (logger.isDebugEnabled()) {
+						logger.debug("Attempting to rename file from the location: "+ fileLocation);
+					}
+
+					if(!files.toString().contains("Decision_")){
+						// Get the file from the saved location
+						File dir = new File(fileLocation);
+						File[] listOfFiles = dir.listFiles();
+
+						for (File file1 : listOfFiles) {
+							if (file1.isFile() && file1.getName().contains( path + removeVersionInFileName)) {
+								try {
+									if (file1.delete()) {
+										if (logger.isDebugEnabled()) {
+											logger.debug("Deleted file: " + file1.toString());
+										}
+										configFileDeleted = true;
+									} else {
+										logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + 
+												"Cannot delete the configuration or action body file in specified location: " + file1.getAbsolutePath());	
+										response.addHeader("error", "deleteConfig");
+										response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+										return;
+									}
+								} catch (Exception e) {
+									PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Failed to Delete file");	
+								}
+							}
+							configFileDeleted = true;
+						}
+					} else {
+						configFileDeleted = true;
+					}
+
+					//Delete the Policy from Database Policy Version table
+					if (policyFileDeleted && configFileDeleted) {
+						String removeExtension = domain + removeVersionInFileName;
+						EntityManager em = (EntityManager) emf.createEntityManager();
+
+						Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
+						Query getPolicyScore = em.createQuery("Select p from PolicyScore p where p.PolicyName=:pname");
+						getPolicyVersion.setParameter("pname", removeExtension);
+						getPolicyScore.setParameter("pname", removeExtension);
+
+						@SuppressWarnings("rawtypes")
+						List pvResult = getPolicyVersion.getResultList();
+						@SuppressWarnings("rawtypes")
+						List psResult = getPolicyScore.getResultList();
+
+
+						try{
+							em.getTransaction().begin();
+							if (!pvResult.isEmpty()) {
+								for (Object id : pvResult) {
+									PolicyVersion versionEntity = (PolicyVersion)id;	
+									em.remove(versionEntity);
+								}
+							} else {
+								logger.debug("No PolicyVersion record found in database.");
+							}
+
+							if (!psResult.isEmpty()) {				
+								for (Object id : psResult) {
+									PolicyScore scoreEntity = (PolicyScore)id;	
+									em.remove(scoreEntity);
+								}
+							} else {
+								PolicyLogger.error("No PolicyScore record found in database.");
+							}
+							em.getTransaction().commit();
+							policyVersionScoreDeleted = true;
+						}catch(Exception e){
+							em.getTransaction().rollback();
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
+							response.addHeader("error", "deleteDB");
+							response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+							return;
+						} finally {
+							em.close();
+						}
+					}
+				}
+			}
+			//If Specific version is requested for delete
+		} else if (policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
+			String policyScoreName = domain + file.getName().toString();
+			String policyVersionName = policyScoreName.substring(0, policyScoreName.indexOf("."));
+			String versionExtension = policyScoreName.substring(policyScoreName.indexOf(".")+1);
+			String removexmlExtension = file.toString().substring(0, file.toString().lastIndexOf("."));
+			String getVersion = removexmlExtension.substring(removexmlExtension.indexOf(".")+1);
+			String removeVersion = removexmlExtension.substring(0, removexmlExtension.lastIndexOf("."));
+
+
+			JPAUtils jpaUtils = null;
+			try {
+				jpaUtils = JPAUtils.getJPAUtilsInstance(emf);
+			} catch (Exception e) {
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP");
+				e.printStackTrace();
+				response.addHeader("error", "jpautils");
+				response.addHeader("operation", "delete");
+				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+				return;
+			}
+
+			if (jpaUtils.dbLockdownIgnoreErrors()) {
+				logger.warn("Policies are locked down");
+				response.addHeader("lockdown", "true");
+				response.addHeader("operation", "delete");
+				response.setStatus(HttpServletResponse.SC_ACCEPTED);
+				return;
+			}
+
+			//Propagates delete to the database 
+			Boolean deletedFromDB = notifyDBofDelete(file.toString());
+
+			if (deletedFromDB) {
+				logger.info("Policy deleted from the database.  Continuing with file delete");
+			} else {
+				PolicyLogger.error("Failed to delete Policy from database. Aborting file delete");
+				response.addHeader("error", "deleteDB");
+				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+				return;
+			}
+
+			if (file.delete()) {
+				if (logger.isDebugEnabled()) {
+					logger.debug("Deleted file: " + file.toString());
+				}
+				policyFileDeleted = true;
+			} else {
+				logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + 
+						"Cannot delete the policy file in specified location: " + file.getAbsolutePath());	
+				response.addHeader("error", "deleteFile");
+				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+				return;
+			}
+
+			// Get tomcat home directory for deleting config data
+			logger.info("print the path:" +domain);
+			String path = domain.replace('\\', '.');
+			if(path.contains("/")){
+				path = path.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			String fileName = FilenameUtils.removeExtension(file.getName());
+			String removeVersionInFileName = fileName.substring(0, fileName.lastIndexOf("."));
+			String fileLocation = null;
+
+			if(CONFIG_HOME == null){
+				CONFIG_HOME = getConfigHome();
+			}
+			if(ACTION_HOME == null){
+				ACTION_HOME = getActionHome();
+			}
+
+
+			if (fileName != null && fileName.contains("Config_")) {
+				fileLocation = CONFIG_HOME;
+			} else if (fileName != null && fileName.contains("Action_")) {
+				fileLocation = ACTION_HOME;
+			}
+
+			if (logger.isDebugEnabled()) {
+				logger.debug("Attempting to rename file from the location: "+ fileLocation);
+			}
+
+			if(!file.toString().contains("Decision_")){
+				// Get the file from the saved location
+				File dir = new File(fileLocation);
+				File[] listOfFiles = dir.listFiles();
+
+				for (File file1 : listOfFiles) {
+					if (file1.isFile() && file1.getName().contains( path + fileName)) {
+						try {
+							if (file1.delete()) {
+								if (logger.isDebugEnabled()) {
+									logger.debug("Deleted file: " + file1.toString());
+								}
+								configFileDeleted = true;
+							} else {
+								logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + 
+										"Cannot delete the configuration or action body file in specified location: " + file1.getAbsolutePath());	
+								response.addHeader("error", "deleteConfig");
+								response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+								return;
+							}
+						} catch (Exception e) {
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Failed to Delete file");		
+						}
+					}
+					configFileDeleted = true;
+				}
+			} else {
+				configFileDeleted = true;
+			}
+
+			//Delete the Policy from Database and set Active Version based on the deleted file.
+			int highestVersion = 0;
+			if (policyFileDeleted && configFileDeleted) {
+				String removeExtension = domain + removeVersionInFileName;
+				EntityManager em = (EntityManager) emf.createEntityManager();
+
+				Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
+				Query getPolicyScore = em.createQuery("Select p from PolicyScore p where p.PolicyName=:pname");
+				getPolicyVersion.setParameter("pname", removeExtension);
+				getPolicyScore.setParameter("pname", removeExtension);
+
+				@SuppressWarnings("rawtypes")
+				List pvResult = getPolicyVersion.getResultList();
+				@SuppressWarnings("rawtypes")
+				List psResult = getPolicyScore.getResultList();
+
+
+				try{
+					em.getTransaction().begin();
+					if (!pvResult.isEmpty()) {
+						PolicyVersion versionEntity = null;
+						for (Object id : pvResult) {
+							versionEntity = (PolicyVersion)id;
+							if(versionEntity.getPolicyName().equals(removeExtension)){
+								highestVersion = versionEntity.getHigherVersion();
+								em.remove(versionEntity);
+							}
+						}
+
+						int i = 0;
+						int version = Integer.parseInt(getVersion);
+
+						if(version == highestVersion) {
+							for(i = highestVersion; i>=1; i--){
+								highestVersion = highestVersion - 1;
+								String dirXML = removeVersion + "." + highestVersion + ".xml";
+								File filenew = new File(dirXML);
+
+								if(filenew.exists()){
+									break;
+								}
+
+							}
+						}
+
+						versionEntity.setPolicyName(removeExtension);
+						versionEntity.setHigherVersion(highestVersion);
+						versionEntity.setActiveVersion(highestVersion);
+						versionEntity.setModifiedBy("API");	
+
+						em.persist(versionEntity);
+
+					} else {
+						logger.debug("No PolicyVersion record found in database.");
+					}
+
+					if (!psResult.isEmpty()) {				
+						for (Object id : psResult) {
+							PolicyScore scoreEntity = (PolicyScore)id;	
+							if(scoreEntity.getPolicyName().equals(policyVersionName) && scoreEntity.getVersionExtension().equals(versionExtension)){
+								em.remove(scoreEntity);
+							}
+						}
+					} else {
+						PolicyLogger.error("No PolicyScore record found in database.");
+					}
+					em.getTransaction().commit();
+					policyVersionScoreDeleted = true;
+				}catch(Exception e){
+					em.getTransaction().rollback();
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
+					response.addHeader("error", "deleteDB");
+					response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+					return;
+				} finally {
+					em.close();
+				}
+			}
+		}
+
+		if (policyFileDeleted && configFileDeleted && policyVersionScoreDeleted) {
+			response.setStatus(HttpServletResponse.SC_OK);
+			response.addHeader("successMapKey", "success");
+			response.addHeader("operation", "delete");
+			return;				
+		} else {
+			PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
+
+			response.addHeader("error", "unknown");
+			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+			return;
+		}
+
+	}
+
+	private void doImportMicroServicePut(HttpServletRequest request, HttpServletResponse response) {
+		String importServiceCreation = request.getParameter("importService");;
+		String fileName = request.getParameter("fileName");
+		String version = request.getParameter("version");
+		String serviceName = request.getParameter("serviceName");
+		CreateNewMicroSerivceModel newMS = null;
+
+		String randomID = UUID.randomUUID().toString();
+
+		if ( importServiceCreation != null  || fileName != null) {
+			File extracDir = new File("ExtractDir");
+			if (!extracDir.exists()){
+				extracDir.mkdirs();
+			}
+			if (fileName.contains(".xmi")){
+				// get the request content into a String
+				String xmi = null;
+
+				// read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
+				java.util.Scanner scanner;
+				try {
+					scanner = new java.util.Scanner(request.getInputStream());
+					scanner.useDelimiter("\\A");
+					xmi =  scanner.hasNext() ? scanner.next() : "";
+					scanner.close();
+				} catch (IOException e1) {
+					logger.error("Error in reading in file from API call");
+					return;
+				}
+
+				logger.info("XML request from API for import new Service");
+
+				//Might need to seperate by , for more than one file. 
+
+				try (Writer writer = new BufferedWriter(new OutputStreamWriter(
+						new FileOutputStream("ExtractDir" + File.separator + randomID+".xmi"), "utf-8"))) {
+					writer.write(xmi);
+				} catch (IOException e) {
+					logger.error("Error in reading in file from API call");
+					return;
+				}
+			}else{ 
+				try {	
+					InputStream inputStream = request.getInputStream() ; 
+
+					FileOutputStream outputStream = new FileOutputStream("ExtractDir" + File.separator + randomID+".zip"); 
+					byte[] buffer = new byte[4096];
+					int bytesRead = -1 ; 
+					while ((bytesRead = inputStream.read(buffer)) != -1) { 
+						outputStream.write(buffer, 0, bytesRead) ; 
+					} 
+
+					outputStream.close() ; 
+					inputStream.close() ;
+
+				} catch (IOException e) {
+					logger.error("Error in reading in Zip File from API call");
+					return;
+				}
+			}
+
+			newMS =  new CreateNewMicroSerivceModel(fileName, serviceName, "API IMPORT", version, randomID);
+			Map<String, String> successMap = newMS.addValuesToNewModel();
+			if (successMap.containsKey("success")) {
+				successMap.clear();
+				successMap = newMS.saveImportService();
+			}
+
+
+			// create the policy and return a response to the PAP-ADMIN		    
+			if (successMap.containsKey("success")) {							
+				response.setStatus(HttpServletResponse.SC_OK);								
+				response.addHeader("successMapKey", "success");								
+				response.addHeader("operation", "import");
+				response.addHeader("service", serviceName);
+			} else if (successMap.containsKey("DBError")) {
+				if (successMap.get("DBError").contains("EXISTS")){
+					response.setStatus(HttpServletResponse.SC_CONFLICT);
+					response.addHeader("service", serviceName);
+					response.addHeader("error", "modelExistsDB");
+				}else{
+					response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+					response.addHeader("error", "importDB");
+				}
+				response.addHeader("operation", "import");
+				response.addHeader("service", serviceName);
+			}else if (successMap.get("error").contains("MISSING")){
+				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+				response.addHeader("error", "missing");	
+				response.addHeader("operation", "import");
+				response.addHeader("service", serviceName);
+			}
+		}
+	}
+
+	private void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response, ECOMPLoggingContext loggingContext) throws ServletException, IOException {
+
+		String policyName = request.getParameter("policyName");
+		String groupId = request.getParameter("groupId");
+		String responseString = null;
+
+		// for PUT operations the group may or may not need to exist before the operation can be done
+		EcompPDPGroup group = null;
+		try {
+			group = papEngine.getGroup(groupId);
+		} catch (PAPException e) {
+			logger.error("Exception occured While PUT operation is performing for PDP Group"+e);
+		}
+
+		if (group == null) {
+			String message = "Unknown groupId '" + groupId + "'";
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			response.addHeader("error", "UnknownGroup");
+			response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
+			return;
+		} else {
+
+			loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
+
+			if (policyName.contains("xml")) {
+				logger.debug("The full file name including the extension was provided for policyName.. continue.");
+			} else {
+				String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
+						+ "policyName must be the full name of the file to be deleted including version and extension";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
+						+ "policyName must be the full name of the file to be deleted including version and extension");
+				response.addHeader("error", "invalidPolicyName");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+				return;
+			}
+			RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
+
+			PDPPolicy policy =  group.getPolicy(policyName);
+
+			if (policy != null) {
+				removePolicy.prepareToRemove(policy);
+				EcompPDPGroup updatedGroup = removePolicy.getUpdatedObject();
+				responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
+			} else {
+				String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
+				response.addHeader("error", "noPolicyExist");
+				response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
+				return;
+			}			
+		}
+
+		if (responseString.equals("success")) {
+			logger.info("Policy successfully deleted!");
+			PolicyLogger.audit("Policy successfully deleted!");
+			response.setStatus(HttpServletResponse.SC_OK);
+			response.addHeader("successMapKey", "success");
+			response.addHeader("operation", "delete");
+			return;		
+		} else if (responseString.equals("No Group")) {
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
+			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+			response.addHeader("error", "groupUpdate");
+			response.addHeader("message", message);
+			return;	
+		} else if (responseString.equals("DB Error")) {
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
+			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+			response.addHeader("error", "deleteDB");
+			return;
+		} else {
+			PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
+			response.addHeader("error", "unknown");
+			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+			return;
+		}
+
+	}
+
+	protected String getParentPathSubScopeDir(File file) {
+		String domain1 = null;
+
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+
+		String policyDir = file.getAbsolutePath();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		if(policyDir.contains("Config_")){
+			domain1 = policyDir.substring(0,policyDir.indexOf("Config_"));
+		}else if(policyDir.contains("Action_")){
+			domain1 = policyDir.substring(0,policyDir.indexOf("Action_"));	
+		}else{
+			domain1 = policyDir.substring(0,policyDir.indexOf("Decision_"));	
+		}
+		logger.info("print the main domain value"+policyDir);
+
+		return domain1;
+	}
+
+	/*
+	 * method to delete the policy from the database and return notification when using API
+	 */
+	private Boolean notifyDBofDelete (String policyToDelete) {
+		//String policyToDelete = request.getParameter("policyToDelete");
+		try{
+			policyToDelete = URLDecoder.decode(policyToDelete,"UTF-8");
+		} catch(UnsupportedEncodingException e){
+			PolicyLogger.error("Unsupported URL encoding of policyToDelete (UTF-8)");
+			return false;
+		}
+		PolicyDBDaoTransaction deleteTransaction = policyDBDao.getNewTransaction();
+		try{
+			deleteTransaction.deletePolicy(policyToDelete);
+		} catch(Exception e){
+			deleteTransaction.rollbackTransaction();
+			return false;
+		}
+		deleteTransaction.commitTransaction();
+		return true;
+	}
+
+	private String deletePolicyFromPDPGroup (EcompPDPGroup group, ECOMPLoggingContext loggingContext){
+		PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction();
+
+		String response = null;
+		loggingContext.setServiceName("API:PAP.updateGroup");
+
+		EcompPDPGroup existingGroup = null;
+		try {
+			existingGroup = papEngine.getGroup(group.getId());
+		} catch (PAPException e1) {
+			logger.error("Exception occured While Deleting Policy From PDP Group"+e1);
+		}
+
+		if (group == null ||
+				! (group instanceof StdPDPGroup) ||
+				! (group.getId().equals(existingGroup.getId()))) {
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingGroup.getId() + " objectFromJSON="+group);
+			loggingContext.transactionEnded();
+
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+
+			response = "No Group";
+			return response;
+		}
+
+		// The Path on the PAP side is not carried on the RESTful interface with the AC
+		// (because it is local to the PAP)
+		// so we need to fill that in before submitting the group for update
+		((StdPDPGroup)group).setDirectory(((StdPDPGroup)existingGroup).getDirectory());
+
+		try{
+			acPutTransaction.updateGroup(group, "XACMLPapServlet.doAPIDelete");
+		} catch(Exception e){
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
+					+"group="+existingGroup.getId());
+			response = "DB Error";
+			return response;
+		}
+
+		try {
+			papEngine.updateGroup(group);
+		} catch (PAPException e) {
+			logger.error("Exception occured While Updating PDP Groups"+e);
+			response = "error in updateGroup method";
+		}
+
+		if (logger.isDebugEnabled()) {
+			logger.debug("Group '" + group.getId() + "' updated");
+		}
+
+		acPutTransaction.commitTransaction();
+
+		// Group changed, which might include changing the policies
+		try {
+			groupChanged(existingGroup);
+		}  catch (Exception e) {
+			logger.error("Exception occured in Group Change Method"+e);
+			response = "error in groupChanged method";
+		}
+
+		if (response==null){
+			response = "success";
+			PolicyLogger.audit("Policy successfully deleted!");
+			PolicyLogger.audit("Transaction Ended Successfully");
+		}
+
+		loggingContext.transactionEnded();
+		PolicyLogger.audit("Transaction Ended");
+		return response;
+	}
+
+
+	//
+	// Heartbeat thread - periodically check on PDPs' status
+	//
+
+	/**
+	 * Heartbeat with all known PDPs.
+	 * 
+	 * Implementation note:
+	 * 
+	 * The PDPs are contacted Sequentially, not in Parallel.
+	 * 
+	 * If we did this in parallel using multiple threads we would simultaneously use
+	 * 		- 1 thread and
+	 * 		- 1 connection
+	 * for EACH PDP.
+	 * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
+	 * when user changes occur.
+	 * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
+	 * 
+	 * The Sequential operation does a heartbeat request to each PDP one at a time.
+	 * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout.
+	 * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
+	 * it could take a long time to cycle through all of the PDPs.
+	 * That means that this may not notice a PDP being down in a predictable time.
+	 * 
+	 *
+	 */
+	private class Heartbeat implements Runnable {
+		private PAPPolicyEngine papEngine;
+		private Set<EcompPDP> pdps = new HashSet<EcompPDP>();
+		private int heartbeatInterval;
+		private int heartbeatTimeout;
+
+		public volatile boolean isRunning = false;
+
+		public synchronized boolean isRunning() {
+			return this.isRunning;
+		}
+
+		public synchronized void terminate() {
+			this.isRunning = false;
+		}
+
+		public Heartbeat(PAPPolicyEngine papEngine2) {
+			this.papEngine = papEngine2;
+			this.heartbeatInterval = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000"));
+			this.heartbeatTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000"));
+		}
+
+		@Override
+		public void run() {
+			//
+			// Set ourselves as running
+			//
+			synchronized(this) {
+				this.isRunning = true;
+			}
+			HashMap<String, URL> idToURLMap = new HashMap<String, URL>();
+			try {
+				while (this.isRunning()) {
+					// Wait the given time
+					Thread.sleep(heartbeatInterval);
+
+					// get the list of PDPs (may have changed since last time)
+					pdps.clear();
+					synchronized(papEngine) {
+						try {
+							for (EcompPDPGroup g : papEngine.getEcompPDPGroups()) {
+								for (EcompPDP p : g.getEcompPdps()) {
+									pdps.add(p);
+								}
+							}
+						} catch (PAPException e) {
+							PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", "Heartbeat unable to read PDPs from PAPEngine");
+						}
+					}
+					//
+					// Check for shutdown
+					//
+					if (this.isRunning() == false) {
+						logger.info("isRunning is false, getting out of loop.");
+						break;
+					}
+
+					// try to get the summary status from each PDP
+					boolean changeSeen = false;
+					for (EcompPDP pdp : pdps) {
+						//
+						// Check for shutdown
+						//
+						if (this.isRunning() == false) {
+							logger.info("isRunning is false, getting out of loop.");
+							break;
+						}
+						// the id of the PDP is its url (though we add a query parameter)
+						URL pdpURL = idToURLMap.get(pdp.getId());
+						if (pdpURL == null) {
+							// haven't seen this PDP before
+							String fullURLString = null;
+							try {
+								// Check PDP ID
+								if(CheckPDP.validateID(pdp.getId())){
+									fullURLString = pdp.getId() + "?type=hb";
+									pdpURL = new URL(fullURLString);
+									idToURLMap.put(pdp.getId(), pdpURL);
+								}
+							} catch (MalformedURLException e) {
+								PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " PDP id '" + fullURLString + "' is not a valid URL");
+								continue;
+							}
+						}
+
+						// Do a GET with type HeartBeat
+						String newStatus = "";
+
+						HttpURLConnection connection = null;
+						try {
+
+							//
+							// Open up the connection
+							//
+							connection = (HttpURLConnection)pdpURL.openConnection();
+							//
+							// Setup our method and headers
+							//
+							connection.setRequestMethod("GET");
+							connection.setConnectTimeout(heartbeatTimeout);
+							// Added for Authentication
+							String encoding = CheckPDP.getEncoding(pdp.getId());
+							if(encoding !=null){
+								connection.setRequestProperty("Authorization", "Basic " + encoding);
+							}
+							//
+							// Do the connect
+							//
+							connection.connect();
+							if (connection.getResponseCode() == 204) {
+								newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB);
+								if (logger.isDebugEnabled()) {
+									logger.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'");
+								}
+							} else {
+								// anything else is an unexpected result
+								newStatus = PDPStatus.Status.UNKNOWN.toString();
+								PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat connect response code " + connection.getResponseCode() + ": " + pdp.getId());
+							}
+						} catch (UnknownHostException e) {
+							newStatus = PDPStatus.Status.NO_SUCH_HOST.toString();
+							PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST");
+						} catch (SocketTimeoutException e) {
+							newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+							PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' connection timeout");
+						} catch (ConnectException e) {
+							newStatus = PDPStatus.Status.CANNOT_CONNECT.toString();
+							PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Heartbeat '" + pdp.getId() + "' cannot connect");
+						} catch (Exception e) {
+							newStatus = PDPStatus.Status.UNKNOWN.toString();
+							PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", "Heartbeat '" + pdp.getId() + "' connect exception");
+						} finally {
+							// cleanup the connection
+							connection.disconnect();
+						}
+
+						if ( ! pdp.getStatus().getStatus().toString().equals(newStatus)) {
+							if (logger.isDebugEnabled()) {
+								logger.debug("previous status='" + pdp.getStatus().getStatus()+"'  new Status='" + newStatus + "'");
+							}
+							try {
+								setPDPSummaryStatus(pdp, newStatus);
+							} catch (PAPException e) {
+								PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", "Unable to set state for PDP '" + pdp.getId());
+							}
+							changeSeen = true;
+						}
+
+					}
+					//
+					// Check for shutdown
+					//
+					if (this.isRunning() == false) {
+						logger.info("isRunning is false, getting out of loop.");
+						break;
+					}
+
+					// if any of the PDPs changed state, tell the ACs to update
+					if (changeSeen) {
+						notifyAC();
+					}
+
+				}
+			} catch (InterruptedException e) {
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat interrupted.  Shutting down");
+				this.terminate();
+			}
+		}
+	}
+
+
+	//
+	// HELPER to change Group status when PDP status is changed
+	//
+	// (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock)
+	//
+
+	private void setPDPSummaryStatus(EcompPDP pdp, PDPStatus.Status newStatus) throws PAPException {
+		setPDPSummaryStatus(pdp, newStatus.toString());
+	}
+
+	private void setPDPSummaryStatus(EcompPDP pdp, String newStatus) throws PAPException {
+		synchronized(papEngine) {
+			StdPDPStatus status = new StdPDPStatus();
+			status.setStatus(PDPStatus.Status.valueOf(newStatus));
+			((StdPDP)pdp).setStatus(status);
+
+			// now adjust the group
+			StdPDPGroup group = (StdPDPGroup)papEngine.getPDPGroup((EcompPDP) pdp);
+			// if the PDP was just deleted it may transiently exist but not be in a group
+			if (group != null) {
+				group.resetStatus();
+			}
+		}
+	}
+
+
+	//
+	// Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine
+	//	in the PDP group directories
+	//
+
+	@Override
+	public void changed() {
+		// all PDPs in all groups need to be updated/sync'd
+		Set<EcompPDPGroup> groups;
+		try {
+			groups = papEngine.getEcompPDPGroups();
+		} catch (PAPException e) {
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed");
+			throw new RuntimeException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e);
+		}
+		for (EcompPDPGroup group : groups) {
+			groupChanged(group);
+		}
+	}
+
+	@Override
+	public void groupChanged(EcompPDPGroup group) {
+		// all PDPs within one group need to be updated/sync'd
+		for (EcompPDP pdp : group.getEcompPdps()) {
+			pdpChanged(pdp);
+		}
+	}
+
+	@Override
+	public void pdpChanged(EcompPDP pdp) {
+		// kick off a thread to do an event notification for each PDP.
+		// This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc)
+		// do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out.
+		// begin - Fix to maintain requestId - including storedRequestId in UpdatePDPThread to be used later when calling PDP
+		// Thread t = new Thread(new UpdatePDPThread(pdp));
+		Thread t = new Thread(new UpdatePDPThread(pdp, storedRequestId));
+		// end   - Fix to maintain requestId
+		if(CheckPDP.validateID(pdp.getId())){
+			t.start();
+		}
+	}
+
+	private class UpdatePDPThread implements Runnable {
+		private EcompPDP pdp;
+		// begin - Fix to maintain requestId - define requestId under class to be used later when calling PDP
+		private String requestId;
+		// end   - Fix to maintain requestId
+
+		// remember which PDP to notify
+		public UpdatePDPThread(EcompPDP pdp) {
+			this.pdp = pdp;
+		}
+
+		// begin - Fix to maintain requestId - clone UpdatePDPThread method with different method signature so to include requestId to be used later when calling PDP
+		public UpdatePDPThread(EcompPDP pdp, String storedRequestId) {
+			this.pdp = pdp;
+			requestId = storedRequestId;
+		}
+		// end   - Fix to maintain requestId
+
+		public void run() {
+			// send the current configuration to one PDP
+			HttpURLConnection connection = null;
+			// get a new logging context for the thread
+			ECOMPLoggingContext loggingContext = new ECOMPLoggingContext(baseLoggingContext);
+			try {
+				loggingContext.setServiceName("PAP:PDP.putConfig");
+				// get a new transaction (request) ID and update the logging context.
+				// begin - Fix to maintain requestId - replace unconditioned generation of new requestID so it won't be used later when calling PDP
+				// If a requestId was provided, use it, otherwise generate one; post to loggingContext to be used later when calling PDP
+				// UUID requestID = UUID.randomUUID();
+				// loggingContext.setRequestID(requestID.toString());
+				if ((requestId == null) || (requestId == "")) {
+					UUID requestID = UUID.randomUUID();
+					loggingContext.setRequestID(requestID.toString());
+					PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (UpdatePDPThread) so we generated one:  " + loggingContext.getRequestID());
+				} else {
+					loggingContext.setRequestID(requestId);
+					PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (UpdatePDPThread):  " + loggingContext.getRequestID());
+				}
+				// end   - Fix to maintain requestId
+				loggingContext.transactionStarted();
+				// dummy metric.log example posted below as proof of concept
+				loggingContext.metricStarted();
+				loggingContext.metricEnded();
+				PolicyLogger.metrics("Metric example posted here - 1 of 2");
+				loggingContext.metricStarted();
+				loggingContext.metricEnded();
+				PolicyLogger.metrics("Metric example posted here - 2 of 2");
+				// dummy metric.log example posted above as proof of concept
+
+				//
+				// the Id of the PDP is its URL
+				//
+				if (logger.isDebugEnabled()) {
+					logger.debug("creating url for id '" + pdp.getId() + "'");
+				}
+				//TODO - currently always send both policies and pips.  Do we care enough to add code to allow sending just one or the other?
+				//TODO		(need to change "cache=", implying getting some input saying which to change)
+				URL url = new URL(pdp.getId() + "?cache=all");
+
+				//
+				// Open up the connection
+				//
+				connection = (HttpURLConnection)url.openConnection();
+				//
+				// Setup our method and headers
+				//
+				connection.setRequestMethod("PUT");
+				// Added for Authentication
+				String encoding = CheckPDP.getEncoding(pdp.getId());
+				if(encoding !=null){
+					connection.setRequestProperty("Authorization", "Basic " + encoding);
+				}
+				connection.setRequestProperty("Content-Type", "text/x-java-properties");
+				// begin - Fix to maintain requestId - post requestID from loggingContext in PDP request header for call to PDP, then reinit storedRequestId to null
+				// connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
+				connection.setRequestProperty("X-ECOMP-RequestID", loggingContext.getRequestID());
+				storedRequestId = null;
+				// end   - Fix to maintain requestId 
+				//
+				// Adding this in. It seems the HttpUrlConnection class does NOT
+				// properly forward our headers for POST re-direction. It does so
+				// for a GET re-direction.
+				//
+				// So we need to handle this ourselves.
+				//
+				//TODO - is this needed for a PUT?  seems better to leave in for now?
+				//	            connection.setInstanceFollowRedirects(false);
+				//
+				// PLD - MUST be able to handle re-directs.
+				//
+				connection.setInstanceFollowRedirects(true);
+				connection.setDoOutput(true);
+				try (OutputStream os = connection.getOutputStream()) {
+
+					EcompPDPGroup group = papEngine.getPDPGroup((EcompPDP) pdp);
+					// if the PDP was just deleted, there is no group, but we want to send an update anyway
+					if (group == null) {
+						// create blank properties files
+						Properties policyProperties = new Properties();
+						policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, "");
+						policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, "");
+						policyProperties.store(os, "");
+
+						Properties pipProps = new Properties();
+						pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, "");
+						pipProps.store(os, "");
+
+					} else {
+						// send properties from the current group
+						group.getPolicyProperties().store(os, "");
+						Properties policyLocations = new Properties();
+						for (PDPPolicy policy : group.getPolicies()) {
+							policyLocations.put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId());
+						}
+						policyLocations.store(os, "");
+						group.getPipConfigProperties().store(os, "");
+					}
+
+				} catch (Exception e) {
+					PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to send property file to " + pdp.getId());
+					// Since this is a server-side error, it probably does not reflect a problem on the client,
+					// so do not change the PDP status.
+					return;
+				}
+				//
+				// Do the connect
+				//
+				connection.connect();
+				if (connection.getResponseCode() == 204) {
+					logger.info("Success. We are configured correctly.");
+					loggingContext.transactionEnded();
+					auditLogger.info("Success. PDP is configured correctly.");
+					PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE);
+				} else if (connection.getResponseCode() == 200) {
+					logger.info("Success. PDP needs to update its configuration.");
+					loggingContext.transactionEnded();
+					auditLogger.info("Success. PDP needs to update its configuration.");
+					PolicyLogger.audit("Transaction Success. PDP is configured correctly.");
+					setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH);
+				} else {
+					logger.warn("Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+					loggingContext.transactionEnded();
+					auditLogger.warn("Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+					PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+				}
+			} catch (Exception e) {
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to sync config with PDP '" + pdp.getId() + "'");
+				loggingContext.transactionEnded();
+				PolicyLogger.audit("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e);
+				try {
+					setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN);
+				} catch (PAPException e1) {
+					PolicyLogger.audit("Transaction Failed: Unable to set status of PDP " + pdp.getId() + " to UNKNOWN: " + e);
+
+					PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN");
+				}
+			} finally {
+				// cleanup the connection
+				connection.disconnect();
+
+				// tell the AC to update it's status info
+				notifyAC();
+			}
+
+		}
+	}
+
+	//
+	// RESTful Interface from PAP to ACs notifying them of changes
+	//
+
+	private void notifyAC() {
+		// kick off a thread to do one event notification for all registered ACs
+		// This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data
+		// as part of processing this message on their end.
+		Thread t = new Thread(new NotifyACThread());
+		t.start();
+	}
+
+	private class NotifyACThread implements Runnable {
+
+		public void run() {
+			List<String> disconnectedACs = new ArrayList<String>();
+
+			// There should be no Concurrent exception here because the list is a CopyOnWriteArrayList.
+			// The "for each" loop uses the collection's iterator under the covers, so it should be correct.
+			for (String acURL : adminConsoleURLStringList) {
+				HttpURLConnection connection = null;
+				try {
+
+					acURL += "?PAPNotification=true";
+
+					//TODO - Currently we just tell AC that "Something changed" without being specific.  Do we want to tell it which group/pdp changed?
+					//TODO - If so, put correct parameters into the Query string here
+					acURL += "&objectType=all" + "&action=update";
+
+					if (logger.isDebugEnabled()) {
+						logger.debug("creating url for id '" + acURL + "'");
+					}
+					//TODO - currently always send both policies and pips.  Do we care enough to add code to allow sending just one or the other?
+					//TODO		(need to change "cache=", implying getting some input saying which to change)
+
+					URL url = new URL(acURL );
+
+					//
+					// Open up the connection
+					//
+					connection = (HttpURLConnection)url.openConnection();
+					//
+					// Setup our method and headers
+					//
+					connection.setRequestMethod("PUT");
+					connection.setRequestProperty("Content-Type", "text/x-java-properties");
+					//
+					// Adding this in. It seems the HttpUrlConnection class does NOT
+					// properly forward our headers for POST re-direction. It does so
+					// for a GET re-direction.
+					//
+					// So we need to handle this ourselves.
+					//
+					//TODO - is this needed for a PUT?  seems better to leave in for now?
+					connection.setInstanceFollowRedirects(false);
+					//
+					// Do not include any data in the PUT because this is just a
+					// notification to the AC.
+					// The AC will use GETs back to the PAP to get what it needs
+					// to fill in the screens.
+					//
+
+					//
+					// Do the connect
+					//
+					connection.connect();
+					if (connection.getResponseCode() == 204) {
+						logger.info("Success. We updated correctly.");
+					} else {
+						logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() + "  message: " + connection.getResponseMessage());
+					}
+
+				} catch (Exception e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to sync config AC '" + acURL + "': " + e, e);
+					PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Unable to sync config AC '" + acURL + "'");
+					disconnectedACs.add(acURL);
+				} finally {
+					// cleanup the connection
+					connection.disconnect();
+				}
+			}
+
+			// remove any ACs that are no longer connected
+			if (disconnectedACs.size() > 0) {
+				adminConsoleURLStringList.removeAll(disconnectedACs);
+			}
+
+		}
+	}
+
+	/*
+	 * Added by Mike M in 1602 release for Authorizing the PEP Requests for Granularity. 
+	 */
+	private boolean authorizeRequest(HttpServletRequest request) {
+		if(request instanceof HttpServletRequest) {
+
+			// Get the client Credentials from the Request header. 
+			String clientCredentials = request.getHeader(ENVIRONMENT_HEADER);
+
+			// Check if the Client is Authorized. 
+			if(clientCredentials!=null && clientCredentials.equalsIgnoreCase(environment)){
+				return true;
+			}else{
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	public static String getConfigHome(){
+		try {
+			loadWebapps();
+		} catch (Exception e) {
+			return null;
+		}
+		return CONFIG_HOME;
+	}
+
+	public static String getActionHome(){
+		try {
+			loadWebapps();
+		} catch (Exception e) {
+			return null;
+		}
+		return ACTION_HOME;
+	}
+
+	private static void loadWebapps() throws Exception{
+		if(ACTION_HOME == null || CONFIG_HOME == null){
+			Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS));
+			//Sanity Check
+			if (webappsPath == null) {
+				PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
+				throw new Exception("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
+			}
+			Path webappsPathConfig;
+			Path webappsPathAction;
+			if(webappsPath.toString().contains("\\"))
+			{
+				webappsPathConfig = Paths.get(webappsPath.toString()+"\\Config");
+				webappsPathAction = Paths.get(webappsPath.toString()+"\\Action");
+			}
+			else
+			{
+				webappsPathConfig = Paths.get(webappsPath.toString()+"/Config");
+				webappsPathAction = Paths.get(webappsPath.toString()+"/Action");
+			}
+			if (Files.notExists(webappsPathConfig)) 
+			{
+				try {
+					Files.createDirectories(webappsPathConfig);
+				} catch (IOException e) {
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Failed to create config directory: "
+							+ webappsPathConfig.toAbsolutePath().toString());
+				}
+			}
+			if (Files.notExists(webappsPathAction)) 
+			{
+				try {
+					Files.createDirectories(webappsPathAction);
+				} catch (IOException e) {
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
+							+ webappsPathAction.toAbsolutePath().toString(), e);
+				}
+			}
+			ACTION_HOME = webappsPathAction.toString();
+			CONFIG_HOME = webappsPathConfig.toString();
+		}
+	}
+
+	/**
+	 * @return the emf
+	 */
+	public EntityManagerFactory getEmf() {
+		return emf;
+	}
+	public IntegrityMonitor getIm() {
+		return im;
+	}
+
+	public IntegrityAudit getIa() {
+		return ia;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/GridData.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/GridData.java
new file mode 100644
index 0000000..86f42bc
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/GridData.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.adapters;
+
+import java.util.ArrayList;
+
+public class GridData {
+	private ArrayList<Object> attributes;
+	private ArrayList<Object> alAttributes;
+	private ArrayList<Object> transportProtocols;
+	private ArrayList<Object> appProtocols;
+
+	public ArrayList<Object> getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(ArrayList<Object> attributes) {
+		this.attributes = attributes;
+	}
+
+	public ArrayList<Object> getAlAttributes() {
+		return alAttributes;
+	}
+
+	public void setAlAttributes(ArrayList<Object> alAttributes) {
+		this.alAttributes = alAttributes;
+	}
+
+	public ArrayList<Object> getAppProtocols() {
+		return appProtocols;
+	}
+
+	public void setAppProtocols(ArrayList<Object> appProtocols) {
+		this.appProtocols = appProtocols;
+	}
+
+	public ArrayList<Object> getTransportProtocols() {
+		return transportProtocols;
+	}
+
+	public void setTransportProtocols(ArrayList<Object> transportProtocols) {
+		this.transportProtocols = transportProtocols;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/PolicyRestAdapter.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/PolicyRestAdapter.java
new file mode 100644
index 0000000..19af8b0
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/PolicyRestAdapter.java
@@ -0,0 +1,480 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.adapters;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManagerFactory;
+
+//import org.openecomp.policy.pap.xacml.rest.model.GitRepositoryContainer;
+
+public class PolicyRestAdapter {
+	
+	private Object data;
+	private String policyName = null;
+	private String configBodyData = null;
+	private String configType = null;
+	private String policyID = null;
+	private String policyType = null;
+	private String configPolicyType = null;
+	private String policyDescription = null;
+	private String ecompName = null;
+	private String configName = null;
+	private String ruleID = null;
+	private String ruleCombiningAlgId = null;
+	private Map<String,String> dynamicFieldConfigAttributes;
+	private Map<String,String> dynamicSettingsMap;
+	private Map<String,String> dropDownMap;
+	private String actionPerformer = null;
+	private String actionAttribute = null;
+	private List<String> dynamicRuleAlgorithmLabels;
+	private List<String> dynamicRuleAlgorithmCombo;
+	private List<String> dynamicRuleAlgorithmField1;
+	private List<String> dynamicRuleAlgorithmField2;
+	private List<Object> dynamicVariableList;
+	private List<String> dataTypeList;
+	private String parentPath;	
+	private boolean isValidData = false;
+	private String adminNotification = null;
+	private boolean isEditPolicy = false;
+	private boolean isViewPolicy = false;
+	private boolean isDraft = false;
+	private Object policyData = null;
+	private String gitPath;
+	private boolean readOnly;
+	private String configHome;
+	private String configUrl;
+	private String finalPolicyPath;
+	private String version;
+	private String jsonBody;
+	private String apiflag;
+	private String prevJsonBody;
+	private Integer highestVersion;
+//	private String actionDictHeader = null;
+//	private String actionDictType = null;
+//	private String actionDictUrl = null;
+//	private String actionDictMethod = null;
+	private String serviceType = null;
+	private String uuid = null;
+	private String location = null;
+    private String priority = null;
+	private Map<String,String> brmsParamBody=null;
+	private EntityManagerFactory entityManagerFactory = null;
+	private Boolean policyExists = false;
+	private String policyScope;
+	private String providerComboBox = null;
+	private String riskType;
+	private String guard;
+	private String riskLevel;
+	private String ttlDate;
+	
+
+	public Integer getHighestVersion() {
+		return highestVersion;
+	}
+	public void setHighestVersion(Integer highestVersion) {
+		this.highestVersion = highestVersion;
+	}
+	public Object getData() {
+		return data;
+	}
+	public void setData(Object data) {
+		this.data = data;
+	}
+	public String getPolicyName() {
+		return policyName;
+	}
+	public void setPolicyName(String policyName) {
+		this.policyName = policyName;
+	}
+	public String getConfigBodyData() {
+		return configBodyData;
+	}
+	public void setConfigBodyData(String configBodyData) {
+		this.configBodyData = configBodyData;
+	}
+	public String getConfigType() {
+		return configType;
+	}
+	public void setConfigType(String configType) {
+		this.configType = configType;
+	}
+	public String getPolicyID() {
+		return policyID;
+	}
+	public void setPolicyID(String policyID) {
+		this.policyID = policyID;
+	}
+	public String getPolicyType() {
+		return policyType;
+	}
+	public void setPolicyType(String policyType) {
+		this.policyType = policyType;
+	}
+	public String getPolicyDescription() {
+		return policyDescription;
+	}
+	public void setPolicyDescription(String policyDescription) {
+		this.policyDescription = policyDescription;
+	}
+	public String getEcompName() {
+		return ecompName;
+	}
+	public void setEcompName(String ecompName) {
+		this.ecompName = ecompName;
+	}
+	public String getConfigName() {
+		return configName;
+	}
+	public void setConfigName(String configName) {
+		this.configName = configName;
+	}
+	public String getRuleID() {
+		return ruleID;
+	}
+	public void setRuleID(String ruleID) {
+		this.ruleID = ruleID;
+	}
+	public String getRuleCombiningAlgId() {
+		return ruleCombiningAlgId;
+	}
+	public void setRuleCombiningAlgId(String ruleCombiningAlgId) {
+		this.ruleCombiningAlgId = ruleCombiningAlgId;
+	}
+	public Map<String,String> getDynamicFieldConfigAttributes() {
+		return dynamicFieldConfigAttributes;
+	}
+	public void setDynamicFieldConfigAttributes(
+			Map<String,String> dynamicFieldConfigAttributes) {
+		this.dynamicFieldConfigAttributes = dynamicFieldConfigAttributes;
+	}
+	public String getParentPath() {
+		return parentPath;
+	}
+	public void setParentPath(String parentPath) {
+		this.parentPath = parentPath;
+	}
+	public boolean isEditPolicy() {
+		return isEditPolicy;
+	}
+	public void setEditPolicy(boolean isEditPolicy) {
+		this.isEditPolicy = isEditPolicy;
+	}
+	public boolean isViewPolicy() {
+		return isViewPolicy;
+	}
+	public void setViewPolicy(boolean isViewPolicy) {
+		this.isViewPolicy = isViewPolicy;
+	}
+	public Object getPolicyData() {
+		return policyData;
+	}
+	public void setPolicyData(Object policyData) {
+		this.policyData = policyData;
+	}
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+	public void setReadOnly(boolean readOnly) {
+		this.readOnly = readOnly;
+	}
+	public String getUserGitPath() {
+		return gitPath;
+	}
+	public void setUserGitPath(String gitPath) {
+		this.gitPath = gitPath;
+	}
+	public boolean isValidData() {
+		return isValidData;
+	}
+	public void setValidData(boolean isValidData) {
+		this.isValidData = isValidData;
+	}
+	public String getAdminNotification() {
+		return adminNotification;
+	}
+	public void setAdminNotification(String adminNotification) {
+		this.adminNotification = adminNotification;
+	}
+	public String getConfigHome() {
+		return configHome;
+	}
+	public void setConfigHome(String configHome) {
+		this.configHome = configHome;
+	}
+	public String getConfigUrl() {
+		return configUrl;
+	}
+	public void setConfigUrl(String configUrl) {
+		this.configUrl = configUrl;
+	}
+	public String getFinalPolicyPath() {
+		return finalPolicyPath;
+	}
+	public void setFinalPolicyPath(String finalPolicyPath) {
+		this.finalPolicyPath = finalPolicyPath;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	public String getJsonBody() {
+		return jsonBody;
+	}
+	public void setJsonBody(String jsonBody) {
+		this.jsonBody = jsonBody;
+	}
+	public String getPrevJsonBody() {
+		return prevJsonBody;
+	}
+	public void setPrevJsonBody(String prevJsonBody) {
+		this.prevJsonBody = prevJsonBody;
+	}
+	public String getApiflag() {
+		return apiflag;
+	}
+	public void setApiflag(String apiflag) {
+		this.apiflag = apiflag;
+	}
+	/**
+	 * @return the actionPerformer
+	 */
+	public String getActionPerformer() {
+		return actionPerformer;
+	}
+	/**
+	 * @param actionPerformer the actionPerformer to set
+	 */
+	public void setActionPerformer(String actionPerformer) {
+		this.actionPerformer = actionPerformer;
+	}
+	/**
+	 * @return the actionAttribute
+	 */
+	public String getActionAttribute() {
+		return actionAttribute;
+	}
+	/**
+	 * @param actionAttribute the actionAttribute to set
+	 */
+	public void setActionAttribute(String actionAttribute) {
+		this.actionAttribute = actionAttribute;
+	}
+	/**
+	 * @return the dynamicRuleAlgorithmLabels
+	 */
+	public List<String> getDynamicRuleAlgorithmLabels() {
+		return dynamicRuleAlgorithmLabels;
+	}
+	/**
+	 * @param dynamicRuleAlgorithmLabels the dynamicRuleAlgorithmLabels to set
+	 */
+	public void setDynamicRuleAlgorithmLabels(
+			List<String> dynamicRuleAlgorithmLabels) {
+		this.dynamicRuleAlgorithmLabels = dynamicRuleAlgorithmLabels;
+	}
+	/**
+	 * @return the dynamicRuleAlgorithmCombo
+	 */
+	public List<String> getDynamicRuleAlgorithmCombo() {
+		return dynamicRuleAlgorithmCombo;
+	}
+	/**
+	 * @param dynamicRuleAlgorithmCombo the dynamicRuleAlgorithmCombo to set
+	 */
+	public void setDynamicRuleAlgorithmCombo(List<String> dynamicRuleAlgorithmCombo) {
+		this.dynamicRuleAlgorithmCombo = dynamicRuleAlgorithmCombo;
+	}
+	/**
+	 * @return the dynamicRuleAlgorithmField1
+	 */
+	public List<String> getDynamicRuleAlgorithmField1() {
+		return dynamicRuleAlgorithmField1;
+	}
+	/**
+	 * @param dynamicRuleAlgorithmField1 the dynamicRuleAlgorithmField1 to set
+	 */
+	public void setDynamicRuleAlgorithmField1(
+			List<String> dynamicRuleAlgorithmField1) {
+		this.dynamicRuleAlgorithmField1 = dynamicRuleAlgorithmField1;
+	}
+	/**
+	 * @return the dynamicRuleAlgorithmField2
+	 */
+	public List<String> getDynamicRuleAlgorithmField2() {
+		return dynamicRuleAlgorithmField2;
+	}
+	/**
+	 * @param dynamicRuleAlgorithmField2 the dynamicRuleAlgorithmField2 to set
+	 */
+	public void setDynamicRuleAlgorithmField2(
+			List<String> dynamicRuleAlgorithmField2) {
+		this.dynamicRuleAlgorithmField2 = dynamicRuleAlgorithmField2;
+	}
+	public Map<String,String> getDropDownMap() {
+		return dropDownMap;
+	}
+	public void setDropDownMap(Map<String,String> dropDownMap) {
+		this.dropDownMap = dropDownMap;
+	}
+/*	public String getActionDictHeader() {
+		return actionDictHeader;
+	}
+	public void setActionDictHeader(String actionDictHeader) {
+		this.actionDictHeader = actionDictHeader;
+	}
+	public String getActionDictType() {
+		return actionDictType;
+	}
+	public void setActionDictType(String actionDictType) {
+		this.actionDictType = actionDictType;
+	}
+	public String getActionDictUrl() {
+		return actionDictUrl;
+	}
+	public void setActionDictUrl(String actionDictUrl) {
+		this.actionDictUrl = actionDictUrl;
+	}
+	public String getActionDictMethod() {
+		return actionDictMethod;
+	}
+	public void setActionDictMethod(String actionDictMethod) {
+		this.actionDictMethod = actionDictMethod;
+	}*/
+	public Map<String,String> getDynamicSettingsMap() {
+		return dynamicSettingsMap;
+	}
+	public void setDynamicSettingsMap(Map<String,String> dynamicSettingsMap) {
+		this.dynamicSettingsMap = dynamicSettingsMap;
+	}
+	public List<Object> getDynamicVariableList() {
+		return dynamicVariableList;
+	}
+	public void setDynamicVariableList(List<Object> dynamicVariableList) {
+		this.dynamicVariableList = dynamicVariableList;
+	}
+	public List<String> getDataTypeList() {
+		return dataTypeList;
+	}
+	public void setDataTypeList(List<String> dataTypeList) {
+		this.dataTypeList = dataTypeList;
+	}
+	public boolean isDraft() {
+		return isDraft;
+	}
+	public void setDraft(boolean isDraft) {
+		this.isDraft = isDraft;
+	}
+	public String getConfigPolicyType() {
+		return configPolicyType;
+	}
+	public void setConfigPolicyType(String configPolicyType) {
+		this.configPolicyType = configPolicyType;
+	}
+	public String getServiceType() {
+		return serviceType;
+	}
+	public void setServiceType(String serviceType) {
+		this.serviceType = serviceType;
+	}
+	public String getUuid() {
+		return uuid;
+	}
+	public void setUuid(String uuid) {
+		this.uuid = uuid;
+	}
+	public String getLocation() {
+		return location;
+	}
+	public void setLocation(String location) {
+		this.location = location;
+	}
+    public String getPriority() {
+        return priority;
+    }
+    public void setPriority(String priority) {
+        this.priority = priority;
+    }
+	public Map<String, String> getBrmsParamBody() {
+		return brmsParamBody;
+	}
+	public void setBrmsParamBody(Map<String, String> brmsParamBody) {
+		this.brmsParamBody = brmsParamBody;
+	}
+	public EntityManagerFactory getEntityManagerFactory() {
+		return entityManagerFactory;
+	}
+	public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
+		this.entityManagerFactory = entityManagerFactory;
+	}
+	/**
+	 * @return the policyExists
+	 */
+	public Boolean getPolicyExists() {
+		return policyExists;
+	}
+	/**
+	 * @param policyExists the policyExists to set
+	 */
+	public void setPolicyExists(Boolean policyExists) {
+		this.policyExists = policyExists;
+	}
+	public String getPolicyScope() {
+		return policyScope;
+	}
+	
+	public void setPolicyScope(String domainDir) {
+		this. policyScope=domainDir;
+	}
+	public String getProviderComboBox() {
+		return providerComboBox;
+	}
+	public void setProviderComboBox(String providerComboBox) {
+		this.providerComboBox = providerComboBox;
+	}
+	public String getRiskType() {
+		return riskType;
+	}
+	public void setRiskType(String riskType) {
+		this.riskType = riskType;
+	}
+	public String getGuard() {
+		return guard;
+	}
+	public void setGuard(String guard) {
+		this.guard = guard;
+	}
+	public String getRiskLevel() {
+		return riskLevel;
+	}
+	public void setRiskLevel(String riskLevel) {
+		this.riskLevel = riskLevel;
+	}
+	public String getTtlDate() {
+		return ttlDate;
+	}
+	public void setTtlDate(String ttlDate) {
+		this.ttlDate = ttlDate;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/package-info.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/package-info.java
new file mode 100644
index 0000000..fd5f064
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/adapters/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * 
+ */
+/**
+ *
+ */
+package org.openecomp.policy.pap.xacml.rest.adapters;
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ActionPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ActionPolicy.java
new file mode 100644
index 0000000..b6e003c
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ActionPolicy.java
@@ -0,0 +1,626 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Query;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.pap.xacml.rest.util.JPAUtils;
+import org.openecomp.policy.rest.jpa.ActionPolicyDict;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.FunctionDefinition;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class ActionPolicy extends Policy {
+	
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+	
+	public static final String PDP_ACTION = "PDP";
+	public static final String PEP_ACTION = "PEP";
+	public static final String TYPE_ACTION = "REST";
+
+	public static final String GET_METHOD = "GET";
+	public static final String PUT_METHOD = "PUT";
+	public static final String POST_METHOD = "POST";
+
+	public static final String PERFORMER_ATTRIBUTEID = "performer";
+	public static final String TYPE_ATTRIBUTEID = "type";
+	public static final String METHOD_ATTRIBUTEID = "method";
+	public static final String HEADERS_ATTRIBUTEID = "headers";
+	public static final String URL_ATTRIBUTEID = "url";
+	public static final String BODY_ATTRIBUTEID = "body";
+	
+	List<String> dynamicLabelRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldFunctionRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldOneRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldTwoRuleAlgorithms = new LinkedList<String>();
+	
+	protected Map<String, String> dropDownMap = new HashMap<String, String>();
+	
+	public ActionPolicy() {
+		super();
+	}
+	
+	public ActionPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+	
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject() );		
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+		
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Action")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		
+		if (policyAdapter.getData() != null) {
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			Path newFile = getNextFilename(Paths.get(policyAdapter.getParentPath().toString()), policyAdapter.getPolicyType(), policyAdapter.getPolicyName(), version);
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy already Exists, cannot create the policy.");
+				PolicyLogger.error("Policy already Exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			policyName = newFile.getFileName().toString();
+			
+			// Action body is optional so checking value provided or not
+			//String actionBodyString = policyAdapter.getActionBody();
+			String comboDictValue = policyAdapter.getActionAttribute();
+	        String actionBody = getActionPolicyDict(comboDictValue).getBody();
+			if(!(actionBody==null || "".equals(actionBody))){
+				saveActionBody(policyName, actionBody);
+			}
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+			PolicyType actionPolicy = (PolicyType) policyAdapter.getData();
+			
+			actionPolicy.setDescription(policyAdapter.getPolicyDescription());
+			
+			actionPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+
+			AllOfType allOf = new AllOfType();
+			
+			Map<String, String> dynamicFieldComponentAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+			
+			// If there is any dynamic field attributes create the matches here
+			for (String keyField : dynamicFieldComponentAttributes.keySet()) {
+				String key = keyField;
+				String value = dynamicFieldComponentAttributes.get(key);
+				MatchType dynamicMatch = createDynamicMatch(key, value);
+				allOf.getMatch().add(dynamicMatch);
+			}
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			target.getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			actionPolicy.setTarget(target);
+			
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+
+			rule.setEffect(EffectType.PERMIT);
+			rule.setTarget(new TargetType());
+			
+			dynamicLabelRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmLabels();
+			dynamicFieldFunctionRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmCombo();
+			dynamicFieldOneRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmField1();
+			dynamicFieldTwoRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmField2();
+			//dropDownMap = policyAdapter.getDropDownMap();
+			dropDownMap = createDropDownMap();
+						
+			// Rule attributes are optional and dynamic so check and add them to condition.
+			if (dynamicLabelRuleAlgorithms != null && dynamicLabelRuleAlgorithms.size() > 0) {
+				boolean isCompound = false;
+				ConditionType condition = new ConditionType();
+				int index = dynamicFieldOneRuleAlgorithms.size() - 1;
+
+				for (String labelAttr : dynamicLabelRuleAlgorithms) {
+					// if the rule algorithm as a label means it is a compound
+					if (dynamicFieldOneRuleAlgorithms.get(index).toString().equals(labelAttr)) {
+						ApplyType actionApply = new ApplyType();
+
+						String selectedFunction = (String) dynamicFieldFunctionRuleAlgorithms.get(index).toString();
+						String value1 = (String) dynamicFieldOneRuleAlgorithms.get(index).toString();
+						String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+						actionApply.setFunctionId(dropDownMap.get(selectedFunction));
+						actionApply.getExpression().add(new ObjectFactory().createApply(getInnerActionApply(value1)));
+						actionApply.getExpression().add(new ObjectFactory().createApply(getInnerActionApply(value2)));
+						condition.setExpression(new ObjectFactory().createApply(actionApply));
+						isCompound = true;
+					}
+					
+				}
+				// if rule algorithm not a compound
+				if (!isCompound) {
+					condition.setExpression(new ObjectFactory().createApply(getInnerActionApply(dynamicLabelRuleAlgorithms.get(index).toString())));
+				}
+				rule.setCondition(condition);
+			}
+			// set the obligations to rule
+			rule.setObligationExpressions(getObligationExpressions());
+			actionPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(actionPolicy);
+		}  else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}	
+
+		setPreparedToSave(true);
+		return true;
+	}
+	
+	// Saving the json Configurations file if exists at server location for action policy.
+	private void saveActionBody(String policyName, String actionBodyData) {
+		int version = 0;
+		int highestVersion = 0;
+		String domain = getParentPathSubScopeDir();
+		String path = domain.replace('\\', '.');
+		String removeExtension = policyName.substring(0, policyName.indexOf(".xml"));
+		String removeVersion = removeExtension.substring(0, removeExtension.indexOf("."));
+		if (policyAdapter.isEditPolicy()) {
+			highestVersion = policyAdapter.getHighestVersion();
+			if(highestVersion != 0){
+				version = highestVersion + 1;	
+			}
+		} else {
+			version = 1;
+		}
+		if(path.contains("/")){
+			path = domain.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		try {
+
+			File file = new File(ACTION_HOME + File.separator + path + "." + removeVersion + "." + version + ".json");
+			
+			if (logger.isDebugEnabled())
+				logger.debug("The action body is at " + file.getAbsolutePath());
+
+			// if file doesn't exists, then create it
+			if (!file.exists()) {
+				file.createNewFile();
+			}
+			File configHomeDir = new File(ACTION_HOME);
+			File[] listOfFiles = configHomeDir.listFiles();
+			if (listOfFiles != null){
+				for(File eachFile : listOfFiles){
+					if(eachFile.isFile()){
+						String fileNameWithoutExtension = FilenameUtils.removeExtension(eachFile.getName());
+						String actionFileNameWithoutExtension = FilenameUtils.removeExtension(path + "." + policyName);
+						if (fileNameWithoutExtension.equals(actionFileNameWithoutExtension)){
+							//delete the file
+							if (logger.isInfoEnabled())
+								logger.info("Deleting action body is at " + eachFile.getAbsolutePath());
+							eachFile.delete();
+						}
+					}
+				}
+			}
+			FileWriter fw = new FileWriter(file.getAbsoluteFile());
+			BufferedWriter bw = new BufferedWriter(fw);
+			bw.write(actionBodyData);
+			bw.close();
+
+			if (logger.isInfoEnabled()) {
+				logger.info("Action Body is succesfully saved at " + file.getAbsolutePath());
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+	
+	// Data required for obligation part is setting here.
+	private ObligationExpressionsType getObligationExpressions() {
+		
+		// TODO: add code to get all these values from dictionary
+		ObligationExpressionsType obligations = new ObligationExpressionsType();
+
+		ObligationExpressionType obligation = new ObligationExpressionType();
+        String comboDictValue = policyAdapter.getActionAttribute();
+		obligation.setObligationId(comboDictValue);
+		obligation.setFulfillOn(EffectType.PERMIT);
+
+		// Add Action Assignment:
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId(PERFORMER_ATTRIBUTEID);
+		assignment1.setCategory(CATEGORY_RECIPIENT_SUBJECT);
+
+		AttributeValueType actionNameAttributeValue = new AttributeValueType();
+		actionNameAttributeValue.setDataType(STRING_DATATYPE);
+		actionNameAttributeValue.getContent().add(performer.get(policyAdapter.getActionPerformer()));
+
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(actionNameAttributeValue));
+		obligation.getAttributeAssignmentExpression().add(assignment1);
+
+		// Add Type Assignment:
+		AttributeAssignmentExpressionType assignmentType = new AttributeAssignmentExpressionType();
+		assignmentType.setAttributeId(TYPE_ATTRIBUTEID);
+		assignmentType.setCategory(CATEGORY_RESOURCE);
+
+		AttributeValueType typeAttributeValue = new AttributeValueType();
+		typeAttributeValue.setDataType(STRING_DATATYPE);
+		String actionDictType = getActionPolicyDict(comboDictValue).getType();
+		typeAttributeValue.getContent().add(actionDictType);
+
+		assignmentType.setExpression(new ObjectFactory().createAttributeValue(typeAttributeValue));
+		obligation.getAttributeAssignmentExpression().add(assignmentType);
+
+		// Add Rest_URL Assignment:
+		AttributeAssignmentExpressionType assignmentURL = new AttributeAssignmentExpressionType();
+		assignmentURL.setAttributeId(URL_ATTRIBUTEID);
+		assignmentURL.setCategory(CATEGORY_RESOURCE);
+
+		AttributeValueType actionURLAttributeValue = new AttributeValueType();
+		actionURLAttributeValue.setDataType(URI_DATATYPE);
+		String actionDictUrl = getActionPolicyDict(comboDictValue).getUrl();
+		actionURLAttributeValue.getContent().add(actionDictUrl);
+
+		assignmentURL.setExpression(new ObjectFactory().createAttributeValue(actionURLAttributeValue));
+		obligation.getAttributeAssignmentExpression().add(assignmentURL);
+
+		// Add Method Assignment:
+		AttributeAssignmentExpressionType assignmentMethod = new AttributeAssignmentExpressionType();
+		assignmentMethod.setAttributeId(METHOD_ATTRIBUTEID);
+		assignmentMethod.setCategory(CATEGORY_RESOURCE);
+
+		AttributeValueType methodAttributeValue = new AttributeValueType();
+		methodAttributeValue.setDataType(STRING_DATATYPE);
+		String actionDictMethod = getActionPolicyDict(comboDictValue).getMethod();
+		methodAttributeValue.getContent().add(actionDictMethod);
+
+		assignmentMethod.setExpression(new ObjectFactory().createAttributeValue(methodAttributeValue));
+		obligation.getAttributeAssignmentExpression().add(assignmentMethod);
+
+		// Add JSON_URL Assignment:
+		String actionBody = getActionPolicyDict(comboDictValue).getBody();
+		if (!actionBody.equals(null)) {
+		//if(!(actionBody==null || "".equals(actionBody))){
+			AttributeAssignmentExpressionType assignmentJsonURL = new AttributeAssignmentExpressionType();
+			assignmentJsonURL.setAttributeId(BODY_ATTRIBUTEID);
+			assignmentJsonURL.setCategory(CATEGORY_RESOURCE);
+
+			AttributeValueType jsonURLAttributeValue = new AttributeValueType();
+			jsonURLAttributeValue.setDataType(URI_DATATYPE);
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());;
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex1 = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex1, policyDir.length());
+			logger.info("print the main domain value"+policyDir);
+			String path = policyDir.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			jsonURLAttributeValue.getContent().add(CONFIG_URL + "/Action/" +  path + "." +FilenameUtils.removeExtension(policyName) + ".json");
+
+			assignmentJsonURL.setExpression(new ObjectFactory().createAttributeValue(jsonURLAttributeValue));
+			obligation.getAttributeAssignmentExpression().add(assignmentJsonURL);
+		}
+
+		if(!getActionPolicyDict(comboDictValue).getHeader().equals(null)){
+			String headerVal = getActionPolicyDict(comboDictValue).getHeader();
+			if(headerVal != null && !headerVal.equals("")){
+				// parse it on : to get number of headers
+				String[] result = headerVal.split(":");
+				System.out.println(Arrays.toString(result));
+				for (String eachString : result){
+					// parse each value on =
+					String[] textFieldVals = eachString.split("=");
+					obligation.getAttributeAssignmentExpression().add(addDynamicHeaders(textFieldVals[0], textFieldVals[1]));
+				}
+			}
+
+		}
+			
+		obligations.getObligationExpression().add(obligation);
+		return obligations;
+	}
+
+	
+	// if compound setting the inner apply here
+	protected ApplyType getInnerActionApply(String value1Label) {
+		ApplyType actionApply = new ApplyType();
+		int index = 0;
+		// check the index for the label.
+		for (String labelAttr : dynamicLabelRuleAlgorithms) {
+			if (labelAttr.equals(value1Label)) {
+				String value1 = dynamicFieldOneRuleAlgorithms.get(index).toString();
+				// check if the row contains label again
+				for (String labelValue : dynamicLabelRuleAlgorithms) {
+					if (labelValue.equals(value1)) {
+						return getCompoundApply(index);
+					}
+				}
+
+				// Getting the values from the form.
+				String functionKey = dynamicFieldFunctionRuleAlgorithms.get(index).toString();
+				String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+				actionApply.setFunctionId(dropDownMap.get(functionKey));
+				// if two text field are rule attributes.
+				if ((value1.contains(RULE_VARIABLE)) && (value2.contains(RULE_VARIABLE))) {
+					ApplyType innerActionApply1 = new ApplyType();
+					ApplyType innerActionApply2 = new ApplyType();
+					AttributeDesignatorType attributeDesignator1 = new AttributeDesignatorType();
+					AttributeDesignatorType attributeDesignator2 = new AttributeDesignatorType();
+					// If selected function is Integer function set integer functionID
+					if (functionKey.toLowerCase().contains("integer")) {
+						innerActionApply1.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY);
+						innerActionApply2.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY);
+						attributeDesignator1.setDataType(INTEGER_DATATYPE);
+						attributeDesignator2.setDataType(INTEGER_DATATYPE);
+					} else {
+						// If selected function is not a Integer function
+						// set String functionID
+						innerActionApply1.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+						innerActionApply2.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+						attributeDesignator1.setDataType(STRING_DATATYPE);
+						attributeDesignator2.setDataType(STRING_DATATYPE);
+					}
+					attributeDesignator1.setCategory(CATEGORY_RESOURCE);
+					attributeDesignator2.setCategory(CATEGORY_RESOURCE);
+
+					// Here set actual field values
+					attributeDesignator1.setAttributeId(value1.contains("resource:") ? value1.substring(9): value1.substring(8));
+					attributeDesignator2.setAttributeId(value1.contains("resource:") ? value1.substring(9): value1.substring(8));
+
+					innerActionApply1.getExpression().add(new ObjectFactory().createAttributeDesignator(attributeDesignator1));
+					innerActionApply2.getExpression().add(new ObjectFactory().createAttributeDesignator(attributeDesignator2));
+
+					actionApply.getExpression().add(new ObjectFactory().createApply(innerActionApply1));
+					actionApply.getExpression().add(new ObjectFactory().createApply(innerActionApply2));
+
+				} else {// if either of one text field is rule attribute.
+					ApplyType innerActionApply = new ApplyType();
+					AttributeDesignatorType attributeDesignator = new AttributeDesignatorType();
+					AttributeValueType actionConditionAttributeValue = new AttributeValueType();
+
+					if (functionKey.toLowerCase().contains("integer")) {
+						innerActionApply.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY);
+						actionConditionAttributeValue.setDataType(INTEGER_DATATYPE);
+						attributeDesignator.setDataType(INTEGER_DATATYPE);
+					} else {
+						innerActionApply.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+						actionConditionAttributeValue.setDataType(STRING_DATATYPE);
+						attributeDesignator.setDataType(STRING_DATATYPE);
+					}
+
+					String attributeId = null;
+					String attributeValue = null;
+
+					// Find which textField has rule attribute and set it as
+					attributeId = value1;
+					attributeValue = value2;
+
+					if (attributeId != null) {
+						attributeDesignator.setCategory(CATEGORY_RESOURCE);
+						attributeDesignator.setAttributeId(attributeId);
+					}
+					actionConditionAttributeValue.getContent().add(attributeValue);
+					innerActionApply.getExpression().add(new ObjectFactory().createAttributeDesignator(attributeDesignator));
+					// Decide the order of element based the values.
+					if (attributeId.equals(value1)) {
+						actionApply.getExpression().add(new ObjectFactory().createApply(innerActionApply));
+						actionApply.getExpression().add(new ObjectFactory().createAttributeValue(actionConditionAttributeValue));
+					} else {
+						actionApply.getExpression().add(new ObjectFactory().createAttributeValue(actionConditionAttributeValue));
+						actionApply.getExpression().add(new ObjectFactory().createApply(innerActionApply));
+					}
+				}
+			}
+			index++;
+		}
+		return actionApply;
+	}
+
+	// if the rule algorithm is multiple compound one setting the apply
+	protected ApplyType getCompoundApply(int index) {
+		ApplyType actionApply = new ApplyType();
+		String selectedFunction = dynamicFieldFunctionRuleAlgorithms.get(index).toString();
+		String value1 = dynamicFieldOneRuleAlgorithms.get(index).toString();
+		String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+		actionApply.setFunctionId(dropDownMap.get(selectedFunction));
+		actionApply.getExpression().add(new ObjectFactory().createApply(getInnerActionApply(value1)));
+		actionApply.getExpression().add(new ObjectFactory().createApply(getInnerActionApply(value2)));
+		return actionApply;
+	}
+		
+	// Adding the dynamic headers if any
+	private AttributeAssignmentExpressionType addDynamicHeaders(String header, String value) {
+		AttributeAssignmentExpressionType assignmentHeaders = new AttributeAssignmentExpressionType();
+		assignmentHeaders.setAttributeId("headers:" + header);
+		assignmentHeaders.setCategory(CATEGORY_RESOURCE);
+
+		AttributeValueType headersAttributeValue = new AttributeValueType();
+		headersAttributeValue.setDataType(STRING_DATATYPE);
+		headersAttributeValue.getContent().add(value);
+
+		assignmentHeaders.setExpression(new ObjectFactory().createAttributeValue(headersAttributeValue));
+		return assignmentHeaders;
+	}
+	
+	private Map<String,String> createDropDownMap(){
+		JPAUtils jpaUtils = null;
+		try {
+			jpaUtils = JPAUtils.getJPAUtilsInstance(policyAdapter.getEntityManagerFactory());
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		Map<Datatype, List<FunctionDefinition>> functionMap = jpaUtils.getFunctionDatatypeMap();
+		Map<String, String> dropDownMap = new HashMap<String, String>();
+		for (Datatype id : functionMap.keySet()) {
+			List<FunctionDefinition> functionDefinitions = (List<FunctionDefinition>) functionMap
+					.get(id);
+			for (FunctionDefinition functionDef : functionDefinitions) {
+				dropDownMap.put(functionDef.getShortname(),functionDef.getXacmlid());
+			}
+		}
+		
+		return dropDownMap;
+	}
+	
+	private ActionPolicyDict getActionPolicyDict(String attributeName){
+		ActionPolicyDict retObj = new ActionPolicyDict();
+		//EntityManagerFactory emf = policyAdapter.getEntityManagerFactory();
+		//EntityManager em = emf.createEntityManager();
+		EntityManager em = policyAdapter.getEntityManagerFactory().createEntityManager();
+		Query getActionPolicyDicts = em.createNamedQuery("ActionPolicyDict.findAll");	
+		List<?> actionPolicyDicts = getActionPolicyDicts.getResultList(); 	
+		
+		for (Object id : actionPolicyDicts) {
+			//ActionPolicyDict actionPolicyList = actionPolicyDicts.getItem(id).getEntity();
+			ActionPolicyDict actionPolicy = (ActionPolicyDict) id;
+			if(attributeName.equals(actionPolicy.getAttributeName())){
+				retObj = actionPolicy;
+				break;
+			}
+		}
+		
+		try{
+		em.getTransaction().commit();
+		} catch(Exception e){
+			try{
+				em.getTransaction().rollback();
+			} catch(Exception e2){
+				e2.printStackTrace();
+			}
+		}
+		em.close();
+		
+		return retObj;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}
+
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/AutoPushPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/AutoPushPolicy.java
new file mode 100644
index 0000000..61498e2
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/AutoPushPolicy.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
+import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine;
+
+import com.att.research.xacml.api.pap.PAPEngine;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
+import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
+/**
+ * Auto Push Policy based on the property file properties. 
+ * 
+ * @version 0.1
+ */
+public class AutoPushPolicy {
+	
+	private static final Logger logger = FlexLogger.getLogger(AutoPushPolicy.class);
+	
+	private String filePath = null;
+	private Properties properties;
+	private Long newModified;
+	private Long oldModified;
+	private File propFile;
+	
+	
+	/**
+	 * Constructor Pass in the property file path. 
+	 */
+	public AutoPushPolicy(String file){
+		filePath = file;
+		properties = new Properties();
+		propFile = Paths.get(filePath).toFile();
+		readFile();
+	}
+	
+	/**
+	 * Checks Policy with all the Groups which has set such Property. 
+	 * Else returns Empty Set. 
+	 * 
+	 * @param policyToCreateUpdate
+	 * @param papEngine
+	 */
+	public Set<StdPDPGroup> checkGroupsToPush(String policyToCreateUpdate, PAPPolicyEngine papEngine) {
+		Set<StdPDPGroup> changedGroups= new HashSet<StdPDPGroup>();
+		// Check if the file has been modified. then re-load the properties file. 
+		newModified = propFile.lastModified();
+		try {
+			if(newModified!=oldModified){
+				// File has been updated.
+				readFile();
+			}
+			// Read the File name as its made.
+			String gitPath  = PolicyDBDao.getGitPath();
+			String policyId =  policyToCreateUpdate.substring(policyToCreateUpdate.indexOf(gitPath)+gitPath.length()+1);
+			String policyName = policyId.substring(policyId.lastIndexOf(File.separator)+1,policyId.lastIndexOf("."));
+			policyName = policyName.substring(0,policyName.lastIndexOf("."));
+			policyId = policyId.replace("/", ".");
+			if(policyId.contains("\\")){
+				policyId = policyId.replace("\\", ".");
+			}
+			logger.info("Policy ID : " + policyId);
+			logger.info("Policy Name : " + policyName);
+			// Read in Groups 
+			for(EcompPDPGroup pdpGroup: papEngine.getEcompPDPGroups()){
+				String groupName = pdpGroup.getName();
+				Boolean typeFlag = false;
+				Boolean scopeFlag = false;
+				if(properties.containsKey(groupName + ".policyType")){
+					String type= properties.getProperty(groupName + ".policyType").replaceAll(" ","");
+					if(type.equals("")){
+						type = " ";
+					}
+					typeFlag = policyName.contains(type);
+				}
+				if(properties.containsKey(groupName + ".policyScope")){
+					String scope = properties.getProperty(groupName + ".policyScope").replaceAll(" ", "");
+					if(scope.equals("")){
+						scope = " ";
+					}
+					scopeFlag = policyId.contains(scope);
+				}
+				if(typeFlag || scopeFlag){
+					StdPDPGroup group = addToGroup(policyId,policyName, policyToCreateUpdate, (StdPDPGroup)pdpGroup);
+					changedGroups.add(group);
+				}
+			}
+		} catch (Exception e) {
+			//TODO:EELF Cleanup - Remove logger
+ 			//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while processing the auto push for " + policyToCreateUpdate +"\n " + e.getMessage());
+ 			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "AutoPushPolicy", "Error while processing the auto push for " + policyToCreateUpdate);
+		}
+		return changedGroups;
+	}
+	
+	private void readFile(){
+		try {
+			properties.load(new FileInputStream(propFile));
+			oldModified = propFile.lastModified();
+		} catch (Exception e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while loading in the auto push properties file. " + propFile.toString());
+			PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "AutoPushPolicy", "Error while loading in the auto push properties file.");
+		}
+	}
+	
+	private StdPDPGroup addToGroup(String policyId, String policyName, String policyToCreateUpdate, StdPDPGroup pdpGroup) throws Exception{
+		// Add to group. Send Notification. 
+		StdPDPPolicy policy = new StdPDPPolicy(policyId, true, policyName, Paths.get(policyToCreateUpdate).toUri());
+		//Get the current policies from the Group and Add the new one
+        Set<PDPPolicy> currentPoliciesInGroup = pdpGroup.getPolicies();
+        Set<PDPPolicy> policies = new HashSet<PDPPolicy>();
+        if(policy!=null){
+			policies.add(policy);
+		}
+        pdpGroup.copyPolicyToFile(policyId, new FileInputStream(Paths.get(policyToCreateUpdate).toFile()));
+        //If the selected policy is in the group we must remove it because the name is default
+		Iterator<PDPPolicy> policyIterator = policies.iterator();
+		while (policyIterator.hasNext()) {
+			PDPPolicy selPolicy = policyIterator.next();
+			for (PDPPolicy existingPolicy : currentPoliciesInGroup) {
+				if (existingPolicy.getId().equals(selPolicy.getId())) {
+					pdpGroup.removePolicyFromGroup(existingPolicy);
+					logger.debug("Removing policy: " + existingPolicy);
+					break;
+				}
+			}
+		}
+		if(currentPoliciesInGroup!=null){
+            policies.addAll(currentPoliciesInGroup);
+        }
+		pdpGroup.setPolicies(policies);
+		return pdpGroup;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ClosedLoopPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ClosedLoopPolicy.java
new file mode 100644
index 0000000..8c3e34d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ClosedLoopPolicy.java
@@ -0,0 +1,552 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.json.stream.JsonGenerationException;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class ClosedLoopPolicy extends Policy {
+	
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public ClosedLoopPolicy() {
+		super();
+	}
+	
+	public ClosedLoopPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+	
+	//save configuration of the policy based on the policyname
+	private void saveConfigurations(String policyName, String prevPolicyName, String jsonBody) {
+		String domain = getParentPathSubScopeDir();
+		String path = domain.replace('\\', '.');
+		if(path.contains("/")){
+			path = domain.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		try {
+			String body = jsonBody;
+			try {
+				try{
+					//Remove the trapMaxAge in Verification Signature
+					body = body.replace(",\"trapMaxAge\":null", "");
+				}catch(Exception e){
+					logger.debug("No Trap Max Age in JSON body");
+				}
+				this.policyAdapter.setJsonBody(body);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+			System.out.println(body);
+			if(policyName.endsWith(".xml")){
+				policyName	 = policyName.substring(0, policyName.lastIndexOf(".xml"));	
+			}
+			PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator+path + "."+ policyName +".json");
+			out.println(body);
+			out.close();
+
+		} catch (JsonGenerationException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+	
+	//Utility to read json data from the existing file to a string
+	static String readFile(String path, Charset encoding) throws IOException {
+		
+		byte[] encoded = Files.readAllBytes(Paths.get(path));
+		return new String(encoded, encoding);
+		
+	}
+	
+	//create the configuration file based on the policy name on adding the extension as .json 
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".xml")) {
+			filename = filename.substring(0, filename.length() - 4);
+		}
+		filename = filename + ".json";
+		return filename;
+	}
+
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			prepareToSave();
+		}
+		
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject());	
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+		
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+
+		if (policyAdapter.getData() != null) {
+			
+			//delete the closed loop draft file and configuration file, if validation is success after editing the draft policy
+			String prevPolicyName = null;
+			if(policyAdapter.isEditPolicy()){
+				prevPolicyName = "Config_Fault_" + policyAdapter.getPolicyName() + "." + policyAdapter.getHighestVersion() + ".xml";
+
+				if (policyAdapter.isDraft()) {
+					policyName = "Config_Fault_" + policyAdapter.getPolicyName() + "_Draft";
+				} else {
+					policyName = "Config_Fault_" + policyAdapter.getPolicyName();
+				}
+				
+				//delete the closed loop draft configuration file, if validation is success after editing the draft policy
+				final Path gitPath = Paths.get(policyAdapter.getUserGitPath());
+				String policyDir = policyAdapter.getParentPath();
+				int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+				policyDir = policyDir.substring(startIndex, policyDir.length());
+				logger.info("print the main domain value"+policyDir);
+				String path = policyDir.replace('\\', '.');
+				if(path.contains("/")){
+					path = policyDir.replace('/', '.');
+					logger.info("print the path:" +path); 
+				}
+				String fileName = FilenameUtils.removeExtension(policyName);
+
+				final String tempPath = path;
+				String fileLocation = null;
+				if (fileName != null && fileName.contains("Config_Fault_")) {
+					fileLocation = CONFIG_HOME;
+				} 
+				// Get the file from the saved location
+				File dir = new File(fileLocation);
+				File[] listOfFiles = dir.listFiles();
+				for (File file : listOfFiles) {
+					String configFile = null;
+					if(!policyAdapter.isDraft()){
+						configFile = fileName + "_Draft";
+					}else{
+						configFile = fileName;
+					}
+					if (file.isFile() && file.getName().contains( tempPath + "." + configFile)) {
+						try {
+							if (file.delete() == false) {
+								throw new Exception(
+										"No known error, Delete failed");
+							}
+						} catch (Exception e) {
+							logger.error("Failed to Delete file: "
+									+ e.getLocalizedMessage());
+						}
+					}
+				}
+			}
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			String policyName1 = null;
+			if(policyAdapter.isDraft()){
+				policyName1 = policyAdapter.getPolicyName() + "_Draft";
+			}else{
+				policyName1 = policyAdapter.getPolicyName();
+			}
+			
+			Path newFile = this.getNextLoopFilename(Paths.get(policyAdapter.getParentPath()), policyAdapter.getPolicyType(), policyAdapter.getConfigPolicyType(), policyName1, version);
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("File already exists, cannot create the policy.");
+				PolicyLogger.error("File already exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			
+			policyName = newFile.getFileName().toString();
+			
+			// Save the Configurations file with the policy name with extention based on selection.
+			String jsonBody = policyAdapter.getJsonBody();
+			saveConfigurations(policyName, prevPolicyName, jsonBody);
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+			PolicyType faultPolicy = (PolicyType) policyAdapter.getData();
+			
+			faultPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			faultPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			
+			AllOfType allOfOne = new AllOfType();
+			File policyFilePath = new File(policyAdapter.getParentPath().toString(), policyName);
+			String policyDir = policyFilePath.getParentFile().getName();
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = policyDir + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			AllOfType allOf = new AllOfType();
+			// Adding the matches to AllOfType element
+			// Match for Ecomp
+			allOf.getMatch().add(createMatch("ECOMPName", policyAdapter.getEcompName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+			// Adding the target to the policy element
+			faultPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getStackTrace());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "CreateClosedLoopPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType closedMatch = new MatchType();
+			AttributeValueType closedAttributeValue = new AttributeValueType();
+			closedAttributeValue.setDataType(STRING_DATATYPE);
+			closedAttributeValue.getContent().add("Config");
+			closedMatch.setAttributeValue(closedAttributeValue);
+			AttributeDesignatorType closedAttributeDesignator = new AttributeDesignatorType();
+			URI closedURI = null;
+			try {
+				closedURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getStackTrace());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "CreateClosedLoopPolicy", "Exception creating closed URI");
+			}
+			closedAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			closedAttributeDesignator.setDataType(STRING_DATATYPE);
+			closedAttributeDesignator.setAttributeId(new IdentifierImpl(closedURI).stringValue());
+			closedMatch.setAttributeDesignator(closedAttributeDesignator);
+			closedMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(closedMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			faultPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(faultPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+
+		setPreparedToSave(true);
+		return true;
+	}
+
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("faultID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		// For Config file Url if configurations are provided.
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value"+policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+
+		String content = CONFIG_URL +"/Config/" + path + "." + getConfigFile(policyName);
+		System.out.println("URL value :" + content);
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory().createAttributeValue(AttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment2);
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+		}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+		}
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+		assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+
+		advice.getAttributeAssignmentExpression().add(assignment5);
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("RiskType");
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getRiskType());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+
+		advice.getAttributeAssignmentExpression().add(assignment6);
+		
+		AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+		assignment7.setAttributeId("RiskLevel");
+		assignment7.setCategory(CATEGORY_RESOURCE);
+		assignment7.setIssuer("");
+
+		AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+		configNameAttributeValue7.setDataType(STRING_DATATYPE);
+		configNameAttributeValue7.getContent().add(policyAdapter.getRiskLevel());
+		assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+		advice.getAttributeAssignmentExpression().add(assignment7);	
+
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("guard");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getGuard());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);
+		
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("TTLDate");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getTtlDate());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);
+
+
+		
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ConfigPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ConfigPolicy.java
new file mode 100644
index 0000000..a339b15
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/ConfigPolicy.java
@@ -0,0 +1,693 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class ConfigPolicy extends Policy {
+
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+
+	private String configBodyData;
+
+	public ConfigPolicy() {
+		super();
+	}
+	
+	public ConfigPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+
+	// Saving the Configurations file at server location for config policy.
+	protected void saveConfigurations(String policyName) {
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		logger.info("print the main domain value"+policyDir);
+		String path = policyDir.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		
+		try {
+			File file;
+			String configFileName = getConfigFile(policyName);
+			if(CONFIG_HOME.contains("\\"))
+			{
+			 file = new File(CONFIG_HOME + "\\" + path + "."+ configFileName);
+			}
+			else
+			{
+			 file = new File(CONFIG_HOME + "/" + path + "."+ configFileName);
+			}
+			
+			// if file doesnt exists, then create it
+			if (!file.exists()) {
+				file.createNewFile();
+			}
+
+
+			File configHomeDir = new File(CONFIG_HOME);
+			File[] listOfFiles = configHomeDir.listFiles();
+			if (listOfFiles != null){
+				for(File eachFile : listOfFiles){
+					if(eachFile.isFile()){
+						String fileNameWithoutExtension = FilenameUtils.removeExtension(eachFile.getName());
+						String configFileNameWithoutExtension = FilenameUtils.removeExtension(path + "." + configFileName);
+						if (fileNameWithoutExtension.equals(configFileNameWithoutExtension)){
+							//delete the file
+							eachFile.delete();
+						}
+					}
+				}
+			}
+
+			FileWriter fw = new FileWriter(file.getAbsoluteFile());
+			BufferedWriter bw = new BufferedWriter(fw);
+			bw.write(configBodyData);
+			bw.close();
+			if (logger.isDebugEnabled()) {
+				logger.debug("Configuration is succesfully saved");
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	// Here we are adding the extension for the configurations file based on the
+	// config type selection for saving.
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".xml")) {
+			filename = filename.substring(0, filename.length() - 4);
+		}
+		String id = policyAdapter.getConfigType();
+
+		if (id != null) {
+			if (id.equalsIgnoreCase(JSON_CONFIG)) {
+				filename = filename + ".json";
+			}
+			if (id.equalsIgnoreCase(XML_CONFIG)) {
+				filename = filename + ".xml";
+			}
+			if (id.equalsIgnoreCase(PROPERTIES_CONFIG)) {
+				filename = filename + ".properties";
+			}
+			if (id.equalsIgnoreCase(OTHER_CONFIG)) {
+				filename = filename + ".txt";
+			}
+		}
+		return filename;
+	}
+
+	// Validations for Config form
+	/*
+	 * FORM VALIDATION WILL BE DONE BY THE PAP-ADMIN before creating JSON object... 
+	 * BODY VALIDATION WILL BE DONE BY THE PAP-REST after receiving and deserializing the JSON object
+	 */
+	public boolean validateConfigForm() {
+		
+		isValidForm = true;
+		
+		/*
+		 * Validate Text Area Body
+		 */
+		configBodyData = policyAdapter.getConfigBodyData();
+		String id = policyAdapter.getConfigType();
+		if (id != null) {
+			if (id.equals(JSON_CONFIG)) {
+				if (!isJSONValid(configBodyData)) {
+					isValidForm = false;
+				}
+			} else if (id.equals(XML_CONFIG)) {
+				if (!isXMLValid(configBodyData)) {
+					isValidForm = false;
+				}
+			} else if (id.equals(PROPERTIES_CONFIG)) {
+				if (!isPropValid(configBodyData)||configBodyData.equals("")) {
+					isValidForm = false;
+				} 
+			} else if (id.equals(OTHER_CONFIG)) {
+				if (configBodyData.equals("")) {
+					isValidForm = false;
+				}
+			}
+		}
+		return isValidForm;
+
+	}
+
+	// Validation for XML.
+	private boolean isXMLValid(String data) {
+
+		SAXParserFactory factory = SAXParserFactory.newInstance();
+		factory.setValidating(false);
+		factory.setNamespaceAware(true);
+		try {
+			SAXParser parser = factory.newSAXParser();
+			XMLReader reader = parser.getXMLReader();
+			reader.setErrorHandler(new XMLErrorHandler());
+			reader.parse(new InputSource(new StringReader(data)));
+		} catch (ParserConfigurationException e) {
+			return false;
+		} catch (SAXException e) {
+			return false;
+		} catch (IOException e) {
+			return false;
+		}
+		return true;
+
+	}
+
+	// Validation for Properties file.
+	public boolean isPropValid(String prop) {
+
+		Scanner scanner = new Scanner(prop);
+		while (scanner.hasNextLine()) {
+			String line = scanner.nextLine();
+			line.replaceAll("\\s+", "");
+			if (line.startsWith("#")) {
+				continue;
+			} else {
+				if (line.contains("=")) {
+					String[] parts = line.split("=");
+					if (parts.length < 2) {
+						scanner.close();
+						return false;
+					}
+				} else {
+					scanner.close();
+					return false;
+				}
+			}
+		}
+		scanner.close();
+		return true;
+
+	}
+
+	public class XMLErrorHandler implements ErrorHandler {
+
+		public void warning(SAXParseException e) throws SAXException {
+			System.out.println(e.getMessage());
+		}
+
+		public void error(SAXParseException e) throws SAXException {
+			System.out.println(e.getMessage());
+		}
+
+		public void fatalError(SAXParseException e) throws SAXException {
+			System.out.println(e.getMessage());
+		}
+
+	}
+
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject() );		
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		
+		if (policyAdapter.getData() != null) {
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			Path newFile = getNextFilename(Paths.get(policyAdapter.getParentPath().toString()), policyAdapter.getPolicyType(), policyAdapter.getPolicyName(), version);
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("File already exists");
+				PolicyLogger.error("File alrady exists");
+				setPolicyExists(true);
+				return false;
+			}
+			policyName = newFile.getFileName().toString();
+			
+			// Body is optional so checking.
+			configBodyData = policyAdapter.getConfigBodyData();
+			if (!configBodyData.equals("")) {
+				// Save the Configurations file with the policy name with extention based on selection.
+				saveConfigurations(policyName);
+			}
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+	
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+			
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			AllOfType allOfOne = new AllOfType();
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			logger.info("print the main domain value "+policyDir);
+			String path = policyDir.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = path + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			AllOfType allOf = new AllOfType();
+			
+			// Adding the matches to AllOfType element Match for Ecomp
+			allOf.getMatch().add(createMatch("ECOMPName", policyAdapter.getEcompName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			// Match for ConfigName
+			allOf.getMatch().add(createMatch("ConfigName", policyAdapter.getConfigName()));
+			
+			Map<String, String> dynamicFieldConfigAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+			
+			// If there is any dynamic field create the matches here
+			for (String keyField : dynamicFieldConfigAttributes.keySet()) {
+				String key = keyField;
+				String value = dynamicFieldConfigAttributes.get(key);
+				MatchType dynamicMatch = createDynamicMatch(key, value);
+				allOf.getMatch().add(dynamicMatch);
+			}
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "ConfigPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+			configAttributeValue.getContent().add("Config");
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "ConfigPolicy", "Exception creating Config URI");
+			}
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("configID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		
+		// For Config file Url if configurations are provided.
+		if (policyAdapter.getConfigType() != null) {
+			AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+			assignment2.setAttributeId("URLID");
+			assignment2.setCategory(CATEGORY_RESOURCE);
+			assignment2.setIssuer("");
+
+			AttributeValueType AttributeValue = new AttributeValueType();
+			AttributeValue.setDataType(URI_DATATYPE);
+			String policyDir1 = policyAdapter.getParentPath().toString();
+			int startIndex1 = policyDir1.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+			logger.info("print the main domain value"+policyDir1);
+			String path = policyDir1.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir1.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+
+			String content = "$URL" + "/Config/" + path + "." + getConfigFile(policyName);
+			System.out.println("URL value :" + content);
+			AttributeValue.getContent().add(content);
+			assignment2.setExpression(new ObjectFactory().createAttributeValue(AttributeValue));
+
+			advice.getAttributeAssignmentExpression().add(assignment2);
+			AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+			assignment3.setAttributeId("PolicyName");
+			assignment3.setCategory(CATEGORY_RESOURCE);
+			assignment3.setIssuer("");
+
+			AttributeValueType attributeValue3 = new AttributeValueType();
+			attributeValue3.setDataType(STRING_DATATYPE);
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			StringTokenizer tokenizer = null;
+			StringBuffer buffer = new StringBuffer();
+			if (policyDir.contains("\\")) {
+				tokenizer = new StringTokenizer(policyDir, "\\");
+			} else {
+				tokenizer = new StringTokenizer(policyDir, "/");
+			}
+			if (tokenizer != null) {
+				while (tokenizer.hasMoreElements()) {
+					String value = tokenizer.nextToken();
+					buffer.append(value);
+					buffer.append(".");
+				}
+			}
+			fileName = FilenameUtils.removeExtension(fileName);
+			fileName = buffer.toString() + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			attributeValue3.getContent().add(name);
+			assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+			advice.getAttributeAssignmentExpression().add(assignment3);
+
+			AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+			assignment4.setAttributeId("VersionNumber");
+			assignment4.setCategory(CATEGORY_RESOURCE);
+			assignment4.setIssuer("");
+
+			AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+			configNameAttributeValue4.setDataType(STRING_DATATYPE);
+			configNameAttributeValue4.getContent().add(Integer.toString(version));
+			assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+
+			advice.getAttributeAssignmentExpression().add(assignment4);
+
+			AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+			assignment5.setAttributeId("matching:" + this.ECOMPID);
+			assignment5.setCategory(CATEGORY_RESOURCE);
+			assignment5.setIssuer("");
+
+			AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+			configNameAttributeValue5.setDataType(STRING_DATATYPE);
+			configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+			assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+
+			advice.getAttributeAssignmentExpression().add(assignment5);
+
+			AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+			assignment6.setAttributeId("matching:" + this.CONFIGID);
+			assignment6.setCategory(CATEGORY_RESOURCE);
+			assignment6.setIssuer("");
+
+			AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+			configNameAttributeValue6.setDataType(STRING_DATATYPE);
+			configNameAttributeValue6.getContent().add(policyAdapter.getConfigName());
+			assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+
+			advice.getAttributeAssignmentExpression().add(assignment6);
+
+			Map<String, String> dynamicFieldConfigAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+			for (String keyField : dynamicFieldConfigAttributes.keySet()) {
+				String key = keyField;
+				String value = dynamicFieldConfigAttributes.get(key);
+				AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+				assignment7.setAttributeId("matching:" + key);
+				assignment7.setCategory(CATEGORY_RESOURCE);
+				assignment7.setIssuer("");
+
+				AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+				configNameAttributeValue7.setDataType(STRING_DATATYPE);
+				configNameAttributeValue7.getContent().add(value);
+				assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+				advice.getAttributeAssignmentExpression().add(assignment7);
+			}
+		}
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("RiskType");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getRiskType());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);
+		
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("RiskLevel");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getRiskLevel());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);	
+
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("guard");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getGuard());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+		
+		AttributeAssignmentExpressionType assignment11 = new AttributeAssignmentExpressionType();
+		assignment11.setAttributeId("TTLDate");
+		assignment11.setCategory(CATEGORY_RESOURCE);
+		assignment11.setIssuer("");
+
+		AttributeValueType configNameAttributeValue11 = new AttributeValueType();
+		configNameAttributeValue11.setDataType(STRING_DATATYPE);
+		configNameAttributeValue11.getContent().add(policyAdapter.getTtlDate());
+		assignment11.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue11));
+
+		advice.getAttributeAssignmentExpression().add(assignment11);
+		
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsParamPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsParamPolicy.java
new file mode 100644
index 0000000..6e18da5
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsParamPolicy.java
@@ -0,0 +1,896 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher; 
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.rest.XACMLRestProperties;
+
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.util.XACMLProperties;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class CreateBrmsParamPolicy extends Policy {
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger
+			.getLogger(CreateBrmsParamPolicy.class);
+
+	/*
+	 * These are the parameters needed for DB access from the PAP
+	 */
+	private static String papDbDriver = null;
+	private static String papDbUrl = null;
+	private static String papDbUser = null;
+	private static String papDbPassword = null;
+
+	public CreateBrmsParamPolicy() {
+		super();
+	}
+
+	public CreateBrmsParamPolicy(PolicyRestAdapter policyAdapter) {
+		this.policyAdapter = policyAdapter;
+		this.policyAdapter.setConfigType(policyAdapter.getConfigType());
+
+	}
+	
+	public String expandConfigBody(String ruleContents,  
+										Map<String, String> brmsParamBody
+										  ) { 
+			 
+			Set<String> keySet= new HashSet<String>();
+			
+			Map<String,String> copyMap=new HashMap<>();
+			copyMap.putAll(brmsParamBody);
+			copyMap.put("policyName", policyAdapter.getPolicyName());
+			copyMap.put("policyScope", policyAdapter.getPolicyScope());
+			copyMap.put("policyVersion",policyAdapter.getHighestVersion().toString());
+			
+			//Finding all the keys in the Map data-structure.
+			keySet= copyMap.keySet();
+			Iterator<String> iterator = keySet.iterator(); 
+			Pattern p;
+			Matcher m;
+			while(iterator.hasNext()) {
+				//Converting the first character of the key into a lower case. 
+				String input= iterator.next();
+				String output  = Character.toLowerCase(input.charAt(0)) +
+		                   (input.length() > 1 ? input.substring(1) : "");
+				//Searching for a pattern in the String using the key. 
+				p=Pattern.compile("\\$\\{"+output+"\\}");	
+				m=p.matcher(ruleContents);
+				//Replacing the value with the inputs provided by the user in the editor. 
+				String finalInput = copyMap.get(input);
+				if(finalInput.contains("$")){
+					finalInput = finalInput.replace("$", "\\$");
+				}
+				ruleContents=m.replaceAll(finalInput);
+			}
+			System.out.println(ruleContents);
+			return ruleContents; 
+	} 
+			 
+	// Saving the Configurations file at server location for config policy.
+	protected void saveConfigurations(String policyName, String prevPolicyName,
+			String ruleBody) {
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath()
+				.toString());
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		logger.info("print the main domain value" + policyDir);
+		String path = policyDir.replace('\\', '.');
+		if (path.contains("/")) {
+			path = policyDir.replace('/', '.');
+			logger.info("print the path:" + path);
+		}
+
+		
+			String configFileName = getConfigFile(policyName);
+        try{
+			// Getting the previous policy Config Json file to be used for
+			// updating the dictionary tables
+			if (policyAdapter.isEditPolicy()) {
+
+				String prevConfigFileName = getConfigFile(prevPolicyName);
+
+				File oldFile;
+				if (CONFIG_HOME.contains("\\")) {
+					oldFile = new File(CONFIG_HOME + "\\" + path + "."
+							+ prevConfigFileName);
+				} else {
+					oldFile = new File(CONFIG_HOME + "/" + path + "."
+							+ prevConfigFileName);
+				}
+
+				String filepath = oldFile.toString();
+
+				String prevJsonBody = readFile(filepath, StandardCharsets.UTF_8);
+				policyAdapter.setPrevJsonBody(prevJsonBody);
+			}
+
+			File configHomeDir = new File(CONFIG_HOME);
+			File[] listOfFiles = configHomeDir.listFiles();
+			if (listOfFiles != null) {
+				for (File eachFile : listOfFiles) {
+					if (eachFile.isFile()) {
+						String fileNameWithoutExtension = FilenameUtils
+								.removeExtension(eachFile.getName());
+						String configFileNameWithoutExtension = FilenameUtils
+								.removeExtension(configFileName);
+						if (fileNameWithoutExtension
+								.equals(configFileNameWithoutExtension)) {
+							// delete the file
+							eachFile.delete();
+						}
+					}
+				}
+			}
+        }
+        catch(IOException e){
+        	
+        }
+			try {
+				
+				if (policyName.endsWith(".xml")) {
+					policyName = policyName.substring(0,
+							policyName.lastIndexOf(".xml"));
+				}
+				PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator
+						+ path + "." + policyName + ".txt");
+				String expandedBody=expandConfigBody(ruleBody,policyAdapter.getBrmsParamBody());
+				out.println(expandedBody);
+				out.close();
+
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "CreateBrmsParamPolicy", "Exception saving configuration file");
+			}
+	}
+
+	// Utility to read json data from the existing file to a string
+	static String readFile(String path, Charset encoding) throws IOException {
+
+		byte[] encoded = Files.readAllBytes(Paths.get(path));
+		return new String(encoded, encoding);
+
+	}
+
+	// Here we are adding the extension for the configurations file based on the
+	// config type selection for saving.
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".txt")) {
+			filename = filename.substring(0, filename.length() - 3);
+		}
+
+		filename = filename + ".txt";
+		return filename;
+	}
+
+	// Validations for Config form
+	public boolean validateConfigForm() {
+
+		// Validating mandatory Fields.
+		isValidForm = true;
+		return isValidForm;
+
+	}
+
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if (!isPreparedToSave()) {
+			prepareToSave();
+		}
+		// Until here we prepared the data and here calling the method to create
+		// xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(),
+				policyName);
+		
+		Boolean dbIsUpdated = true;
+
+		successMap = new HashMap<String, String>();
+		if (dbIsUpdated) {
+			successMap = createPolicy(newPolicyPath,
+					getCorrectPolicyDataObject());
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Failed to Update the Database Dictionary Tables.");
+			PolicyLogger.error("Failed to Update the Database Dictionary Tables.");
+
+			// remove the new json file
+			String jsonBody = policyAdapter.getPrevJsonBody();
+			saveConfigurations(policyName, "", jsonBody);
+			successMap.put("error", "DB UPDATE");
+		}
+
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;
+	}
+	
+	private String getValueFromDictionary(String templateName){
+		
+		Connection con = null;
+		Statement st = null;
+		ResultSet rs = null;
+		
+		/*
+		 * Retrieve the property values for db access from the xacml.pap.properties
+		 */
+		papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
+		papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
+		papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
+		papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
+		
+		String ruleTemplate=null;
+		
+		try {
+			//Get DB Connection
+			Class.forName(papDbDriver);
+			con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
+			st = con.createStatement();
+			
+			String queryString="select rule from BRMSParamTemplate where param_template_name=\"";
+			queryString=queryString+templateName+"\"";
+			
+			rs = st.executeQuery(queryString);
+			if(rs.next()){
+				ruleTemplate=rs.getString("rule");
+			}
+			rs.close();
+		}catch (ClassNotFoundException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(e.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "CreateBrmsParamPolicy", "Exception querying BRMSParamTemplate");
+			System.out.println(e.getMessage());
+
+		} catch (SQLException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(e.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "CreateBrmsParamPolicy", "Exception querying BRMSParamTemplate");
+			System.out.println(e.getMessage());
+		} finally {
+			try{
+				if (con!=null) con.close();
+				if (rs!=null) rs.close();
+				if (st!=null) st.close();
+			} catch (Exception ex){}
+		}
+		return ruleTemplate;
+		
+	}
+	
+	protected Map<String, String> findType(String rule) {
+		Map<String, String> mapFieldType= new HashMap<String,String>();
+		if(rule!=null){
+			try {
+				String params = "";
+				Boolean flag = false;
+				Boolean comment = false;
+				String lines[] = rule.split("\n");
+				for(String line : lines){
+					if (line.isEmpty() || line.startsWith("//")) {
+						continue;
+					}
+					if (line.startsWith("/*")) {
+						comment = true;
+						continue;
+					}
+					if (line.contains("//")) {
+						if(!(line.contains("http://") || line.contains("https://"))){
+							line = line.split("\\/\\/")[0];
+						}
+					}
+					if (line.contains("/*")) {
+						comment = true;
+						if (line.contains("*/")) {
+							try {
+								comment = false;
+								line = line.split("\\/\\*")[0]
+										+ line.split("\\*\\/")[1].replace("*/", "");
+							} catch (Exception e) {
+								line = line.split("\\/\\*")[0];
+							}
+						} else {
+							line = line.split("\\/\\*")[0];
+						}
+					}
+					if (line.contains("*/")) {
+						comment = false;
+						try {
+							line = line.split("\\*\\/")[1].replace("*/", "");
+						} catch (Exception e) {
+							line = "";
+						}
+					}
+					if (comment) {
+						continue;
+					}
+					if (flag) {
+						params = params + line;
+					}
+					if (line.contains("declare Params")) {
+						params = params + line;
+						flag = true;
+					}
+					if (line.contains("end") && flag) {
+						break;
+					}
+				}
+				params = params.replace("declare Params", "").replace("end", "")
+						.replaceAll("\\s+", "");
+				String[] components = params.split(":");
+				String caption = "";
+				for (int i = 0; i < components.length; i++) {
+					String type = "";
+					if (i == 0) {
+						caption = components[i];
+					}
+					if(caption.equals("")){
+						break;
+					}
+					String nextComponent = "";
+					try {
+						nextComponent = components[i + 1];
+					} catch (Exception e) {
+						nextComponent = components[i];
+					}
+					//If the type is of type String then we add the UI Item and type to the map. 
+					if (nextComponent.startsWith("String")) {
+						type = "String";
+						mapFieldType.put(caption, type);
+						caption = nextComponent.replace("String", "");
+					} else if (nextComponent.startsWith("int")) {
+						type = "int";
+						mapFieldType.put(caption, type);
+						caption = nextComponent.replace("int", "");
+					}
+				}
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "CreateBrmsParamPolicy", "Exception parsing file in findType");
+			}
+		}
+		return mapFieldType;
+	}
+	
+	// This is the method for preparing the policy for saving. We have broken it
+	// out
+	// separately because the fully configured policy is used for multiple
+	// things
+	@Override
+	public boolean prepareToSave() throws Exception {
+		
+		if (isPreparedToSave()) {
+			// we have already done this
+			return true;
+		}
+
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			// version = Integer.parseInt(policyAdapter.getVersion()) + 1;
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+
+		// Create the Instance for pojo, PolicyType object is used in
+		// marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+
+		if (policyAdapter.getData() != null) {
+
+			// Save off everything
+			// making ready all the required elements to generate the action
+			// policy xml.
+			// Get the uniqueness for policy name.
+			String prevPolicyName = null;
+			if (policyAdapter.isEditPolicy()) {
+				prevPolicyName = "Config_BRMS_Param_" + policyAdapter.getPolicyName()
+						+ "." + policyAdapter.getHighestVersion() + ".xml";
+			}
+
+			Path newFile = getNextFilename(
+					Paths.get(policyAdapter.getParentPath().toString()),
+					(policyAdapter.getPolicyType() + "_BRMS_Param"),
+					policyAdapter.getPolicyName(), version);
+
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy already Exists, cannot create the policy.");
+				PolicyLogger.error("Policy already Exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;			
+			}
+			policyName = newFile.getFileName().toString();
+			
+				
+			Map<String,String> ruleAndUIValue= policyAdapter.getBrmsParamBody();
+			String tempateValue= ruleAndUIValue.get("templateName");
+			String valueFromDictionary= getValueFromDictionary(tempateValue);
+			
+			//Get the type of the UI Fields. 
+			Map<String,String> typeOfUIField=findType(valueFromDictionary);
+			String generatedRule=null;
+			String body = "";
+			
+			try {
+				
+				try {
+					body = "/* Autogenerated Code Please Don't change/remove this comment section. This is for the UI purpose. \n\t " +
+								"<$%BRMSParamTemplate=" + tempateValue + "%$> \n */ \n";
+					body = body +  valueFromDictionary + "\n";
+					generatedRule = "rule \"Params\" \n\tsalience 1000 \n\twhen\n\tthen\n\t\tParams params = new Params();";
+					
+					//We first read the map data structure(ruleAndUIValue) received from the PAP-ADMIN
+					//We ignore if the key is "templateName as we are interested only in the UI fields and its value. 
+					//We have one more map data structure(typeOfUIField) created by parsing the Drools rule. 
+					//From the type of the UI field(String/int) we structure whether to put the "" or not. 
+					for (Map.Entry<String, String> entry : ruleAndUIValue.entrySet()) {
+						if(entry.getKey()!="templateName")
+						{
+							for(Map.Entry<String, String> fieldType:typeOfUIField.entrySet())
+							{
+								if(fieldType.getKey().equalsIgnoreCase(entry.getKey()))
+								{
+									String key = entry.getKey().substring(0, 1).toUpperCase() + entry.getKey().substring(1); 
+									if(fieldType.getValue()=="String")
+									{
+										//Type is String
+										generatedRule = generatedRule + "\n\t\tparams.set"
+												+ key + "(\""
+												+ entry.getValue() + "\");";
+									}
+									else{
+										generatedRule = generatedRule + "\n\t\tparams.set"
+												+ key  + "("
+												+  entry.getValue() + ");";
+									}
+								}
+							}
+						}
+					}
+					
+					generatedRule = generatedRule
+							+ "\n\t\tinsert(params);\nend";
+					logger.info("New rule generated with :" + generatedRule);
+					body = body + generatedRule;
+				} catch (Exception e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
+					PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "CreateBrmsParamPolicy", "Exception saving policy");
+				}
+			}
+			catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "CreateBrmsParamPolicy", "Exception saving policy");
+			}
+			
+			saveConfigurations(policyName,prevPolicyName,body);
+
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter
+					.getRuleCombiningAlgId());
+
+			AllOfType allOfOne = new AllOfType();
+			File policyFilePath = new File(policyAdapter.getParentPath()
+					.toString(), policyName);
+			String policyDir = policyFilePath.getParentFile().getName();
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = policyDir + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1,
+					fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1,
+						fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			
+			
+			AllOfType allOf = new AllOfType();
+
+			// Match for ECOMPName
+			allOf.getMatch().add(
+					createMatch("ECOMPName", policyAdapter.getEcompName()));
+			allOf.getMatch().add(
+					createMatch("ConfigName", policyAdapter.getConfigName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+
+			rule.setEffect(EffectType.PERMIT);
+
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+						//+ e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateBrmsParamPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(
+					accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+
+			configAttributeValue.getContent().add("Config");
+
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+						//+ e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateBrmsParamPolicy", "Exception creating Config URI");
+			}
+
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(
+					configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy
+					.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()
+					.add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object."
+					//+ policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object."
+					+ policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version,
+			String fileName) {
+
+		//Policy Config ID Assignment
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("BRMSPARAMID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment1);
+
+		// For Config file Url if configurations are provided.
+		// URL ID Assignment
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath()
+				.toString());
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value" + policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if (path.contains("/")) {
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" + path);
+		}
+		String content = CONFIG_URL + "/Config/" + path + "."
+				+ getConfigFile(policyName);
+
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory()
+				.createAttributeValue(AttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment2);
+
+		// Policy Name Assignment
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+		}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		System.out.println(fileName);
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1,
+				fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1,
+					fileName.length());
+		}
+		System.out.println(name);
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory()
+				.createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		// Version Number Assignment
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue4));
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		// Ecomp Name Assignment
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+		assignment5.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue5));
+		advice.getAttributeAssignmentExpression().add(assignment5);
+		
+		
+		//Config Name Assignment
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("matching:" + this.CONFIGID);
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getConfigName());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+		advice.getAttributeAssignmentExpression().add(assignment6);
+		
+		Map<String, String> dynamicFieldConfigAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+		for (String keyField : dynamicFieldConfigAttributes.keySet()) {
+			String key = keyField;
+			String value = dynamicFieldConfigAttributes.get(key);
+			AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+			assignment7.setAttributeId("key:" + key);
+			assignment7.setCategory(CATEGORY_RESOURCE);
+			assignment7.setIssuer("");
+
+			AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+			configNameAttributeValue7.setDataType(STRING_DATATYPE);
+			configNameAttributeValue7.getContent().add(value);
+			assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+			advice.getAttributeAssignmentExpression().add(assignment7);
+		}
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("RiskType");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getRiskType());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);
+		
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("RiskLevel");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getRiskLevel());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);	
+
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("guard");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getGuard());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+
+		AttributeAssignmentExpressionType assignment11 = new AttributeAssignmentExpressionType();
+		assignment11.setAttributeId("TTLDate");
+		assignment11.setCategory(CATEGORY_RESOURCE);
+		assignment11.setIssuer("");
+
+		AttributeValueType configNameAttributeValue11 = new AttributeValueType();
+		configNameAttributeValue11.setDataType(STRING_DATATYPE);
+		configNameAttributeValue11.getContent().add(policyAdapter.getTtlDate());
+		assignment11.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue11));
+
+		advice.getAttributeAssignmentExpression().add(assignment11);
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {		
+		return policyAdapter.getData();
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsRawPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsRawPolicy.java
new file mode 100644
index 0000000..d77abf0
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateBrmsRawPolicy.java
@@ -0,0 +1,661 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+
+public class CreateBrmsRawPolicy extends Policy {
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger
+			.getLogger(CreateBrmsRawPolicy.class);
+
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+
+	public CreateBrmsRawPolicy() {
+		super();
+	}
+
+	public CreateBrmsRawPolicy(PolicyRestAdapter policyAdapter) {
+		this.policyAdapter = policyAdapter;
+		this.policyAdapter.setConfigType(policyAdapter.getConfigType());
+
+	}
+
+	// Saving the Configurations file at server location for config policy.
+	protected void saveConfigurations(String policyName, String prevPolicyName,
+			String jsonBody) {
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath()
+				.toString());
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		logger.info("print the main domain value" + policyDir);
+		String path = policyDir.replace('\\', '.');
+		if (path.contains("/")) {
+			path = policyDir.replace('/', '.');
+			logger.info("print the path:" + path);
+		}
+
+		try {
+			String configFileName = getConfigFile(policyName);
+
+			File file;
+			if (CONFIG_HOME.contains("\\")) {
+				file = new File(CONFIG_HOME + "\\" + path + "."
+						+ configFileName);
+			} else {
+				file = new File(CONFIG_HOME + "/" + path + "." + configFileName);
+			}
+
+			// if file doesnt exists, then create it
+			if (!file.exists()) {
+				file.createNewFile();
+			}
+
+			// Getting the previous policy Config Json file to be used for
+			// updating the dictionary tables
+			if (policyAdapter.isEditPolicy()) {
+
+				String prevConfigFileName = getConfigFile(prevPolicyName);
+
+				File oldFile;
+				if (CONFIG_HOME.contains("\\")) {
+					oldFile = new File(CONFIG_HOME + "\\" + path + "."
+							+ prevConfigFileName);
+				} else {
+					oldFile = new File(CONFIG_HOME + "/" + path + "."
+							+ prevConfigFileName);
+				}
+
+				String filepath = oldFile.toString();
+
+				String prevJsonBody = readFile(filepath, StandardCharsets.UTF_8);
+				policyAdapter.setPrevJsonBody(prevJsonBody);
+			}
+
+			File configHomeDir = new File(CONFIG_HOME);
+			File[] listOfFiles = configHomeDir.listFiles();
+			if (listOfFiles != null) {
+				for (File eachFile : listOfFiles) {
+					if (eachFile.isFile()) {
+						String fileNameWithoutExtension = FilenameUtils
+								.removeExtension(eachFile.getName());
+						String configFileNameWithoutExtension = FilenameUtils
+								.removeExtension(configFileName);
+						if (fileNameWithoutExtension
+								.equals(configFileNameWithoutExtension)) {
+							// delete the file
+							eachFile.delete();
+						}
+					}
+				}
+			}
+
+			/*FileWriter fw = new FileWriter(file.getAbsoluteFile());
+			BufferedWriter bw = new BufferedWriter(fw);
+			bw.write(jsonBody);
+			bw.close();
+			if (logger.isDebugEnabled()) {
+				logger.debug("Configuration is succesfully saved");
+			}*/
+			
+			try {
+				
+				if (policyName.endsWith(".xml")) {
+					policyName = policyName.substring(0,
+							policyName.lastIndexOf(".xml"));
+				}
+				PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator
+						+ path + "." + policyName + ".txt");
+				out.println(jsonBody);
+				out.close();
+
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "CreateBrmsRawPolicy", "Exception saving configurations file");
+			}
+			
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	// Utility to read json data from the existing file to a string
+	static String readFile(String path, Charset encoding) throws IOException {
+
+		byte[] encoded = Files.readAllBytes(Paths.get(path));
+		return new String(encoded, encoding);
+
+	}
+
+	// Here we are adding the extension for the configurations file based on the
+	// config type selection for saving.
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".txt")) {
+			filename = filename.substring(0, filename.length() - 3);
+		}
+
+		filename = filename + ".txt";
+		return filename;
+	}
+
+	// Validations for Config form
+	public boolean validateConfigForm() {
+
+		// Validating mandatory Fields.
+		isValidForm = true;
+		return isValidForm;
+
+	}
+
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if (!isPreparedToSave()) {
+			prepareToSave();
+		}
+		// Until here we prepared the data and here calling the method to create
+		// xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(),
+				policyName);
+		
+		Boolean dbIsUpdated = true;
+
+		successMap = new HashMap<String, String>();
+		if (dbIsUpdated) {
+			successMap = createPolicy(newPolicyPath,
+					getCorrectPolicyDataObject());
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Failed to Update the Database Dictionary Tables.");
+			PolicyLogger.error("Failed to Update the Database Dictionary Tables.");
+
+			// remove the new json file
+			String jsonBody = policyAdapter.getPrevJsonBody();
+			saveConfigurations(policyName, "", jsonBody);
+			successMap.put("error", "DB UPDATE");
+		}
+
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;
+	}
+
+	// This is the method for preparing the policy for saving. We have broken it
+	// out
+	// separately because the fully configured policy is used for multiple
+	// things
+	@Override
+	public boolean prepareToSave() throws Exception {
+
+		if (isPreparedToSave()) {
+			// we have already done this
+			return true;
+		}
+
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			// version = Integer.parseInt(policyAdapter.getVersion()) + 1;
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+
+		// Create the Instance for pojo, PolicyType object is used in
+		// marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+
+		if (policyAdapter.getData() != null) {
+
+			// Save off everything
+			// making ready all the required elements to generate the action
+			// policy xml.
+			// Get the uniqueness for policy name.
+			String prevPolicyName = null;
+			if (policyAdapter.isEditPolicy()) {
+				prevPolicyName = "Config_BRMS_Raw_" + policyAdapter.getPolicyName()
+						+ "." + policyAdapter.getHighestVersion() + ".xml";
+			}
+			//if (!policyAdapter.isEditPolicy()) {
+				Path newFile = getNextFilename(
+						Paths.get(policyAdapter.getParentPath().toString()),
+						(policyAdapter.getPolicyType() + "_BRMS_Raw"),
+						policyAdapter.getPolicyName(), version);
+	
+				if (newFile == null) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("File already exists, cannot create the policy.");
+					PolicyLogger.error("File already exists, cannot create the policy.");
+					setPolicyExists(true);
+					return false;
+				}
+				policyName = newFile.getFileName().toString();
+			//}
+
+			//String jsonBody = policyAdapter.getJsonBody();
+			String configBody=policyAdapter.getConfigBodyData();
+			saveConfigurations(policyName, prevPolicyName, configBody);
+
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter
+					.getRuleCombiningAlgId());
+
+			AllOfType allOfOne = new AllOfType();
+			File policyFilePath = new File(policyAdapter.getParentPath()
+					.toString(), policyName);
+			String policyDir = policyFilePath.getParentFile().getName();
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = policyDir + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1,
+					fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1,
+						fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			
+			
+			AllOfType allOf = new AllOfType();
+
+			// Match for ECOMPName
+			allOf.getMatch().add(
+					createMatch("ECOMPName", policyAdapter.getEcompName()));
+			allOf.getMatch().add(
+					createMatch("ConfigName", policyAdapter.getConfigName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+
+			rule.setEffect(EffectType.PERMIT);
+
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+						//+ e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateBrmsRawPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(
+					accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+
+			configAttributeValue.getContent().add("Config");
+
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE
+						//+ e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateBrmsRawPolicy", "Exception creating Config URI");
+			}
+
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(
+					configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy
+					.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()
+					.add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object."
+					//+ policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object."
+					+ policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version,
+			String fileName) {
+
+		// Policy Config ID Assignment
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("BRMSRAWID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment1);
+
+		// For Config file Url if configurations are provided.
+		// URL ID Assignment
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath()
+				.toString());
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value" + policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if (path.contains("/")) {
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" + path);
+		}
+		String content = CONFIG_URL + "/Config/" + path + "."
+				+ getConfigFile(policyName);
+
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory()
+				.createAttributeValue(AttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment2);
+
+		// Policy Name Assignment
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString())
+				+ gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+		}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		System.out.println(fileName);
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1,
+				fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1,
+					fileName.length());
+		}
+		System.out.println(name);
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory()
+				.createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		// Version Number Assignment
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue4));
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		// Ecomp Name Assignment
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+		assignment5.setExpression(new ObjectFactory()
+				.createAttributeValue(configNameAttributeValue5));
+		advice.getAttributeAssignmentExpression().add(assignment5);
+		
+		
+		//Config Name Assignment
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("matching:" + this.CONFIGID);
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getConfigName());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+		advice.getAttributeAssignmentExpression().add(assignment6);
+		
+		Map<String, String> dynamicFieldConfigAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+		for (String keyField : dynamicFieldConfigAttributes.keySet()) {
+			String key = keyField;
+			String value = dynamicFieldConfigAttributes.get(key);
+			AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+			assignment7.setAttributeId("key:" + key);
+			assignment7.setCategory(CATEGORY_RESOURCE);
+			assignment7.setIssuer("");
+
+			AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+			configNameAttributeValue7.setDataType(STRING_DATATYPE);
+			configNameAttributeValue7.getContent().add(value);
+			assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+			advice.getAttributeAssignmentExpression().add(assignment7);
+		}
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("RiskType");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getRiskType());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);
+		
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("RiskLevel");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getRiskLevel());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);	
+
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("guard");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getGuard());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+
+		AttributeAssignmentExpressionType assignment11 = new AttributeAssignmentExpressionType();
+		assignment11.setAttributeId("TTLDate");
+		assignment11.setCategory(CATEGORY_RESOURCE);
+		assignment11.setIssuer("");
+
+		AttributeValueType configNameAttributeValue11 = new AttributeValueType();
+		configNameAttributeValue11.setDataType(STRING_DATATYPE);
+		configNameAttributeValue11.getContent().add(policyAdapter.getTtlDate());
+		assignment11.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue11));
+
+		advice.getAttributeAssignmentExpression().add(assignment11);
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getData();
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateClosedLoopPerformanceMetrics.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateClosedLoopPerformanceMetrics.java
new file mode 100644
index 0000000..578efc2
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateClosedLoopPerformanceMetrics.java
@@ -0,0 +1,506 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.json.stream.JsonGenerationException;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class CreateClosedLoopPerformanceMetrics extends Policy {
+	
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public CreateClosedLoopPerformanceMetrics() {
+		super();
+	}
+	
+	public CreateClosedLoopPerformanceMetrics(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+
+	//save configuration of the policy based on the policyname
+	private void saveConfigurations(String policyName, String prevPolicyName, String jsonBody) {
+		String domain = getParentPathSubScopeDir();
+		String path = domain.replace('\\', '.');
+		if(path.contains("/")){
+			path = domain.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		try {
+			String body = null;
+			try {
+				body = jsonBody;
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+			System.out.println(body);
+			if(policyName.endsWith(".xml")){
+				policyName	 = policyName.substring(0, policyName.lastIndexOf(".xml"));	
+			}
+			PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator+path + "."+ policyName +".json");
+			out.println(body);
+			out.close();
+
+		} catch (JsonGenerationException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+	
+	//getting the policy name and setting to configuration on adding .json
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".xml")) {
+			filename = filename.substring(0, filename.length() - 4);
+		}
+		filename = filename +".json";
+		return filename;
+	}
+	
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject() );		
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		
+		if (policyAdapter.getData() != null) {
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			String prevPolicyName = null;
+			if(policyAdapter.isEditPolicy()){
+				prevPolicyName = "Config_PM_" + policyAdapter.getPolicyName() + "." + policyAdapter.getHighestVersion() + ".xml";
+			}
+			
+			Path newFile = this.getNextLoopFilename(Paths.get(policyAdapter.getParentPath()), policyAdapter.getPolicyType(), policyAdapter.getConfigPolicyType(), policyAdapter.getPolicyName(), version);
+
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("File already exists, cannot create the policy.");
+				PolicyLogger.error("File already exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			
+			policyName = newFile.getFileName().toString();
+			
+			// Save the Configurations file with the policy name with extention based on selection.
+			String jsonBody = policyAdapter.getJsonBody();
+			saveConfigurations(policyName, prevPolicyName, jsonBody);
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+	
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+			
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			
+			AllOfType allOfOne = new AllOfType();
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			logger.info("print the main domain value "+policyDir);
+			String path = policyDir.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = path + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			AllOfType allOf = new AllOfType();
+			
+			// Adding the matches to AllOfType element Match for Ecomp
+			allOf.getMatch().add(createMatch("ECOMPName", policyAdapter.getEcompName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			// Match for ServiceType
+			allOf.getMatch().add(createMatch("ServiceType", policyAdapter.getServiceType()));
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateClosedLoopPerformanceMetrics", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+			configAttributeValue.getContent().add("Config");
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "CreateClosedLoopPerformanceMetrics", "Exception creating Config URI");
+			}
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+	
+	// Data required for Advice part is setting here.
+	@SuppressWarnings("static-access")
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("PMID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		// For Config file Url if configurations are provided.
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value"+policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		String content = CONFIG_URL +"/Config/" + path + "." + getConfigFile(policyName);
+		System.out.println("URL value :" + content);
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory().createAttributeValue(AttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment2);
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+		}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+		}
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+		assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+
+		advice.getAttributeAssignmentExpression().add(assignment5);
+
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("matching:" + this.CLOSEDLOOPID);
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getServiceType());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+
+		advice.getAttributeAssignmentExpression().add(assignment6);
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+		assignment7.setAttributeId("RiskType");
+		assignment7.setCategory(CATEGORY_RESOURCE);
+		assignment7.setIssuer("");
+
+		AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+		configNameAttributeValue7.setDataType(STRING_DATATYPE);
+		configNameAttributeValue7.getContent().add(policyAdapter.getRiskType());
+		assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+		advice.getAttributeAssignmentExpression().add(assignment7);
+		
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("RiskLevel");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getRiskLevel());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);	
+
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("guard");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getGuard());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);
+		
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("TTLDate");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getTtlDate());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		// TODO Auto-generated method stub
+		return policyAdapter.getPolicyData();
+	}	
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateNewMicroSerivceModel.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateNewMicroSerivceModel.java
new file mode 100644
index 0000000..73479fd
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/CreateNewMicroSerivceModel.java
@@ -0,0 +1,305 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+//import org.eclipse.emf.common.util.URI;
+//import org.eclipse.emf.ecore.EPackage;
+//import org.eclipse.emf.ecore.resource.Resource;
+//import org.eclipse.emf.ecore.resource.ResourceSet;
+//import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+//import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+import org.openecomp.policy.rest.XACMLRestProperties;
+import org.openecomp.policy.rest.jpa.MicroServiceModels;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.openecomp.policy.rest.util.MSAttributeObject;
+import org.openecomp.policy.rest.util.MSModelUtitils;
+
+import com.att.research.xacml.util.XACMLProperties;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class CreateNewMicroSerivceModel {
+	private static final Logger logger = FlexLogger.getLogger(CreateNewMicroSerivceModel.class);
+	private MicroServiceModels newModel = null;
+	private HashMap<String,MSAttributeObject > classMap = new HashMap<String,MSAttributeObject>();
+	private String directory;
+	
+	/*
+	 * These are the parameters needed for DB access from the PAP
+	 */
+	private static String papDbDriver = null;
+	private static String papDbUrl = null;
+	private static String papDbUser = null;
+	private static String papDbPassword = null;
+	
+	MSModelUtitils utils = new MSModelUtitils();
+
+	public CreateNewMicroSerivceModel(String fileName, String serviceName, String string, String version) {
+		super();
+	}
+
+	public CreateNewMicroSerivceModel(String importFile, String  modelName, String description, String version, String randomID) {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		this.newModel = new MicroServiceModels();
+		this.newModel.setDescription(description);
+		this.newModel.setVersion(version);
+		this.newModel.setModelName(modelName);
+		UserInfo userInfo = new UserInfo();
+		userInfo.setUserLoginId("API");
+		this.newModel.setUserCreatedBy(userInfo);
+		String cleanUpFile = null;
+	
+	    HashMap<String, MSAttributeObject> tempMap = new HashMap<String, MSAttributeObject>();
+	    //Need to delete the file
+	    if (importFile.contains(".zip")){
+	    	extractFolder(randomID + ".zip");
+	        File directory = new File("ExtractDir" + File.separator + randomID);
+	        List<File> fileList = listModelFiles(directory.toString());
+	        //get all the files from a directory
+	        File[] fList = directory.listFiles();
+	        for (File file : fileList){
+	            if (file.isFile()){
+				    tempMap = utils.processEpackage(file.getAbsolutePath());
+				    classMap.putAll(tempMap);
+	            }
+	        }
+	        cleanUpFile = "ExtractDir" + File.separator + randomID + ".zip";
+	        try {
+				FileUtils.deleteDirectory(new File("ExtractDir" + File.separator + randomID));
+				FileUtils.deleteDirectory(new File(randomID));
+				File deleteFile = new File(cleanUpFile); 
+				FileUtils.forceDelete(deleteFile);
+			} catch (IOException e) {
+				logger.error("Failed to unzip model file " + randomID);
+			}
+	    }else {
+		    tempMap = utils.processEpackage("ExtractDir" + File.separator + randomID+".xmi");
+		    classMap.putAll(tempMap);
+		    cleanUpFile = "ExtractDir" + File.separator + randomID+".xmi";
+		    File deleteFile = new File(cleanUpFile); 
+			deleteFile.delete();
+	    }
+
+	    //	addValuesToNewModel();
+
+
+	}
+	
+	private List<File> listModelFiles(String directoryName) {
+		File directory = new File(directoryName);
+		List<File> resultList = new ArrayList<File>();
+		File[] fList = directory.listFiles();
+		for (File file : fList) {
+			if (file.isFile()) {
+				resultList.add(file);
+			} else if (file.isDirectory()) {
+				resultList.addAll(listModelFiles(file.getAbsolutePath()));
+			}
+		}
+		return resultList;
+	}
+
+	private void extractFolder(String zipFile) {
+	    int BUFFER = 2048;
+	    File file = new File(zipFile);
+
+	    ZipFile zip;
+		try {
+			zip = new ZipFile("ExtractDir" + File.separator +file);
+		    String newPath =  zipFile.substring(0, zipFile.length() - 4);
+		    this.directory = "ExtractDir" + File.separator + zipFile.substring(0, zipFile.length() - 4);
+		    new File(newPath).mkdir();
+		    Enumeration zipFileEntries = zip.entries();
+	
+		    // Process each entry
+		    while (zipFileEntries.hasMoreElements())
+		    {
+		        // grab a zip file entry
+		        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+		        String currentEntry = entry.getName();
+		        File destFile = new File("ExtractDir" + File.separator + newPath + File.separator + currentEntry);
+		        File destinationParent = destFile.getParentFile();
+	
+		        destinationParent.mkdirs();
+	
+		        if (!entry.isDirectory())
+		        {
+		            BufferedInputStream is = new BufferedInputStream(zip
+		            .getInputStream(entry));
+		            int currentByte;
+
+		            byte data[] = new byte[BUFFER];
+	
+		            FileOutputStream fos = new FileOutputStream(destFile);
+		            BufferedOutputStream dest = new BufferedOutputStream(fos,
+		            BUFFER);
+	
+		            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
+		                dest.write(data, 0, currentByte);
+		            }
+		            dest.flush();
+		            dest.close();
+		            is.close();
+		        }
+	
+		        if (currentEntry.endsWith(".zip"))
+		        {
+		            extractFolder(destFile.getAbsolutePath());
+		        }
+		    }
+	    } catch (IOException e) {
+			logger.error("Failed to unzip model file " + zipFile);
+		}
+	}
+
+	public Map<String, String> addValuesToNewModel() {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		MSAttributeObject mainClass  = null;
+		ArrayList<String> dependency = null;
+		String subAttribute = null;
+		
+		if (!classMap.containsKey(this.newModel.getModelName())){
+			logger.error("Model Provided does not contain the service name provided in request. Unable to import new model");
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "AddValuesToNewModel", "Unable to pull out required values, file missing service name provided in request");
+			successMap.put("error", "MISSING");
+			return successMap;
+		}
+		mainClass = classMap.get(this.newModel.getModelName());
+		String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
+		this.newModel.setDependency(dependTemp);
+		if (!this.newModel.getDependency().equals("")){
+			dependency = new ArrayList<String>(Arrays.asList(dependTemp.split(",")));	
+			dependency = utils.getFullDependencyList(dependency, classMap);
+			if (!dependency.isEmpty()){
+				for (String element : dependency){
+					MSAttributeObject temp = new MSAttributeObject();
+					if (classMap.containsKey(element)){
+						temp = classMap.get(element);
+						mainClass.addAllRefAttribute(temp.getRefAttribute());
+						mainClass.addAllAttribute(temp.getAttribute());
+					}
+				}
+			}		
+		}
+		subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
+
+		this.newModel.setSub_attributes(subAttribute);
+		this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
+		this.newModel.setRef_attributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
+		successMap.put("success", "success");
+		return successMap;
+		
+	}
+	
+	public Map<String, String> saveImportService(){
+		Map<String, String> successMap = new HashMap<String,String>();
+		
+		Connection con = null;
+		Statement st = null;
+		ResultSet rs = null;
+		String modelName = this.newModel.getModelName();
+		String imported_by = "API";////////////////////////////////////////////
+		String version = this.newModel.getVersion();
+		String insertQuery = null;
+		int ID = 0;
+		
+		/*
+		 * Retrieve the property values for db access from the xacml.pap.properties
+		 */
+		papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
+		papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
+		papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
+		papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
+		
+		try {
+			//Get DB Connection
+			Class.forName(papDbDriver);
+			con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
+			st = con.createStatement();
+			String queryString ="SELECT * FROM MicroServiceModels WHERE modelName='" + modelName + "' AND version='" + version+ "';";
+			rs = st.executeQuery(queryString);
+		
+			if(rs.next()){
+				successMap.put("DBError", "EXISTS");
+				logger.error("Import new service failed.  Service already exists");
+			}else{
+				rs = st.executeQuery("SELECT MAX(ID) AS ID FROM MicroServiceModels;");
+				if(rs.next()){
+					ID = rs.getInt("ID");
+					ID++;
+				}
+	
+				insertQuery = "INSERT INTO MicroServiceModels (ID, modelName, Dependency, DESCRIPTION, attributes, ref_attributes, sub_attributes, version, imported_by) "
+							+ "VALUES("+ID+",'"+modelName+"','"+ this.newModel.getDependency()+"','"+this.newModel.getDescription()+"','"+this.newModel.getAttributes()+
+							"','"+this.newModel.getRef_attributes()+"','"+this.newModel.getSub_attributes()+"','"+version+"','"+imported_by+"')";
+				st.executeUpdate(insertQuery);
+				successMap.put("success", "success");
+			}
+			rs.close();
+		}catch (ClassNotFoundException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(e.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "saveImportService", "Exception querying MicroServiceModels");
+			successMap.put("DBError", "Error Query");
+		} catch (SQLException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(e.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "saveImportService", "Exception querying MicroServiceModels");
+			successMap.put("DBError", "Error Query");
+		} finally {
+			try{
+				if (con!=null) con.close();
+				if (rs!=null) rs.close();
+				if (st!=null) st.close();
+			} catch (Exception ex){}
+		}
+
+		return successMap;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/DecisionPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/DecisionPolicy.java
new file mode 100644
index 0000000..822768f
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/DecisionPolicy.java
@@ -0,0 +1,633 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.pap.xacml.rest.util.JPAUtils;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.DecisionSettings;
+import org.openecomp.policy.rest.jpa.FunctionDefinition;
+import org.openecomp.policy.xacml.std.pip.engines.aaf.AAFEngine;
+
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class DecisionPolicy extends Policy {
+
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+	
+	public static final String PDP_ACTION = "PDP";
+	public static final String PEP_ACTION = "PEP";
+	public static final String TYPE_ACTION = "REST";
+
+	public static final String GET_METHOD = "GET";
+	public static final String PUT_METHOD = "PUT";
+	public static final String POST_METHOD = "POST";
+
+	public static final String PERFORMER_ATTRIBUTEID = "performer";
+	public static final String TYPE_ATTRIBUTEID = "type";
+	public static final String METHOD_ATTRIBUTEID = "method";
+	public static final String HEADERS_ATTRIBUTEID = "headers";
+	public static final String URL_ATTRIBUTEID = "url";
+	public static final String BODY_ATTRIBUTEID = "body";
+	
+	public static final String FUNCTION_NOT = "urn:oasis:names:tc:xacml:1.0:function:not";
+	
+	private static final String AAFProvider = "AAF";
+	//private static final String CustomProvider = "Custom";
+	
+	List<String> dynamicLabelRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldComboRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldOneRuleAlgorithms = new LinkedList<String>();
+	List<String> dynamicFieldTwoRuleAlgorithms = new LinkedList<String>();
+	//List<Object> dynamicVariableList = new LinkedList<Object>();
+	List<String> dataTypeList = new LinkedList<String>();
+	
+	protected Map<String, String> dropDownMap = new HashMap<String, String>();
+	
+
+	public DecisionPolicy() {
+		super();
+	}
+	
+	public DecisionPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+	
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		successMap = createPolicy(newPolicyPath, getCorrectPolicyDataObject());		
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+		
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Decision")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		
+		if (policyAdapter.getData() != null) {
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			Path newFile = getNextFilename(Paths.get(policyAdapter.getParentPath().toString()), policyAdapter.getPolicyType(), policyAdapter.getPolicyName(), version);
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("File already exists, cannot create the policy.");
+				PolicyLogger.error("File already exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			policyName = newFile.getFileName().toString();
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+			PolicyType decisionPolicy = (PolicyType)  policyAdapter.getData();
+			
+			decisionPolicy.setDescription(policyAdapter.getPolicyDescription());
+			
+			decisionPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			AllOfType allOfOne = new AllOfType();
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			logger.info("print the main domain value "+policyDir);
+			String path = policyDir.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = path + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			
+			AllOfType allOf = new AllOfType();
+			
+			// Match for Ecomp
+			allOf.getMatch().add(createMatch("ECOMPName", (policyAdapter.getEcompName())));
+			
+			Map<String, String> dynamicFieldComponentAttributes = policyAdapter.getDynamicFieldConfigAttributes();
+			if(policyAdapter.getProviderComboBox()!=null && policyAdapter.getProviderComboBox().equals(AAFProvider)){
+				dynamicFieldComponentAttributes = new HashMap<String,String>();
+			}
+			
+			// If there is any dynamic field attributes create the matches here
+			for (String keyField : dynamicFieldComponentAttributes.keySet()) {
+				String key = keyField;
+				String value = dynamicFieldComponentAttributes.get(key);
+				MatchType dynamicMatch = createDynamicMatch(key, value);
+				allOf.getMatch().add(dynamicMatch);
+			}
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			target.getAnyOf().add(anyOf);
+			decisionPolicy.setTarget(target);
+
+			Map<String, String> dynamicFieldDecisionSettings = policyAdapter.getDynamicSettingsMap();
+			
+			//dynamicVariableList = policyAdapter.getDynamicVariableList();
+			if(policyAdapter.getProviderComboBox()!=null && policyAdapter.getProviderComboBox().equals(AAFProvider)){
+				dynamicFieldDecisionSettings = new HashMap<String,String>();
+			}
+			
+			// settings are dynamic so check how many rows are added and add all
+			for (String keyField : dynamicFieldDecisionSettings.keySet()) {
+				String key = keyField;
+				String value = dynamicFieldDecisionSettings.get(key);
+				//String dataType = (String) dynamicVariableList.get(counter);
+				String dataType = getDataType(key);
+				VariableDefinitionType dynamicVariable = createDynamicVariable(key, value, dataType);
+				decisionPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(dynamicVariable);
+			}
+
+			createRule(decisionPolicy, true);
+			createRule(decisionPolicy, false);
+		}
+
+		setPreparedToSave(true);
+		return true;
+	}
+	
+	private DecisionSettings findDecisionSettingsBySettingId(String settingId) {
+		DecisionSettings decisionSetting = null;
+		
+		EntityManager em = policyAdapter.getEntityManagerFactory().createEntityManager();
+		Query getDecisionSettings = em.createNamedQuery("DecisionSettings.findAll");
+		List<?> decisionSettingsList = getDecisionSettings.getResultList();
+		
+		for (Object id : decisionSettingsList) {
+			decisionSetting = (DecisionSettings) id;
+			if (decisionSetting.getXacmlId().equals(settingId)) {
+				break;
+			}
+		}
+		return decisionSetting;
+	}
+	
+	private void createRule(PolicyType decisionPolicy, boolean permitRule) {
+		RuleType rule = new RuleType();
+			
+		rule.setRuleId(policyAdapter.getRuleID());
+			
+		if (permitRule) {
+			rule.setEffect(EffectType.PERMIT);
+		} else {
+			rule.setEffect(EffectType.DENY);
+		}
+		rule.setTarget(new TargetType());
+
+		// Create Target in Rule
+		AllOfType allOfInRule = new AllOfType();
+
+		// Creating match for ACCESS in rule target
+		MatchType accessMatch = new MatchType();
+		AttributeValueType accessAttributeValue = new AttributeValueType();
+		accessAttributeValue.setDataType(STRING_DATATYPE);
+		accessAttributeValue.getContent().add("DECIDE");
+		accessMatch.setAttributeValue(accessAttributeValue);
+		AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+		URI accessURI = null;
+		try {
+			accessURI = new URI(ACTION_ID);
+		} catch (URISyntaxException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "DecisionPolicy", "Exception creating ACCESS URI");
+		}
+		accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+		accessAttributeDesignator.setDataType(STRING_DATATYPE);
+		accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+		accessMatch.setAttributeDesignator(accessAttributeDesignator);
+		accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+		
+		dynamicLabelRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmLabels();
+		dynamicFieldComboRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmCombo();
+		dynamicFieldOneRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmField1();
+		dynamicFieldTwoRuleAlgorithms = policyAdapter.getDynamicRuleAlgorithmField2();
+		dropDownMap = createDropDownMap();
+		
+		if(policyAdapter.getProviderComboBox()!=null && policyAdapter.getProviderComboBox().equals(AAFProvider)){
+			// Values for AAF Provider are here for XML Creation. 
+			ConditionType condition = new ConditionType();
+			ApplyType decisionApply = new ApplyType();
+			String selectedFunction = "boolean-equal";
+			
+			AttributeValueType value1 = new AttributeValueType();
+			value1.setDataType(BOOLEAN_DATATYPE);
+			value1.getContent().add("true");
+			
+			AttributeDesignatorType value2 = new AttributeDesignatorType();
+			value2.setAttributeId(AAFEngine.AAF_RESULT);
+			value2.setCategory(CATEGORY_RESOURCE);
+			value2.setDataType(BOOLEAN_DATATYPE);
+			value2.setMustBePresent(false);
+			
+			ApplyType innerDecisionApply = new ApplyType();
+			innerDecisionApply.setFunctionId(FUNCTION_BOOLEAN_ONE_AND_ONLY);
+			innerDecisionApply.getExpression().add(new ObjectFactory().createAttributeDesignator(value2));
+			
+			decisionApply.setFunctionId(dropDownMap.get(selectedFunction));
+			decisionApply.getExpression().add(new ObjectFactory().createAttributeValue(value1));
+			decisionApply.getExpression().add(new ObjectFactory().createApply(innerDecisionApply));
+			condition.setExpression(new ObjectFactory().createApply(decisionApply));
+			if (!permitRule) {
+				ApplyType notOuterApply = new ApplyType();
+				notOuterApply.setFunctionId(FUNCTION_NOT);
+				notOuterApply.getExpression().add(condition.getExpression());
+				condition.setExpression(new ObjectFactory().createApply(notOuterApply));
+			}
+			rule.setCondition(condition);
+			allOfInRule.getMatch().add(accessMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			if(!permitRule){
+				AdviceExpressionsType adviceExpressions = new AdviceExpressionsType();
+				AdviceExpressionType adviceExpression = new AdviceExpressionType();
+				adviceExpression.setAdviceId(AAFProvider);
+				adviceExpression.setAppliesTo(EffectType.DENY);
+				AttributeAssignmentExpressionType assignment = new AttributeAssignmentExpressionType();
+				assignment.setAttributeId("aaf.response");
+				assignment.setCategory(CATEGORY_RESOURCE);
+				AttributeDesignatorType value = new AttributeDesignatorType();
+				value.setAttributeId(AAFEngine.AAF_RESPONSE);
+				value.setCategory(CATEGORY_RESOURCE);
+				value.setDataType(STRING_DATATYPE);
+				value.setMustBePresent(false);
+				assignment.setExpression(new ObjectFactory().createAttributeDesignator(value));
+				adviceExpression.getAttributeAssignmentExpression().add(assignment);
+				adviceExpressions.getAdviceExpression().add(adviceExpression);
+				rule.setAdviceExpressions(adviceExpressions);
+			}
+			decisionPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(decisionPolicy);
+			
+		}else if (dynamicLabelRuleAlgorithms != null && dynamicLabelRuleAlgorithms.size() > 0) {
+			boolean isCompound = false;
+			ConditionType condition = new ConditionType();
+			int index = dynamicFieldOneRuleAlgorithms.size() - 1;
+			
+			for (String labelAttr : dynamicLabelRuleAlgorithms) {
+				// if the rule algorithm as a label means it is a compound
+				if (dynamicFieldOneRuleAlgorithms.get(index).toString().equals(labelAttr)) {
+					ApplyType decisionApply = new ApplyType();
+
+					String selectedFunction = (String) dynamicFieldComboRuleAlgorithms.get(index).toString();
+					String value1 = (String) dynamicFieldOneRuleAlgorithms.get(index).toString();
+					String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+					decisionApply.setFunctionId(dropDownMap.get(selectedFunction));
+					decisionApply.getExpression().add(new ObjectFactory().createApply(getInnerDecisionApply(value1)));
+					decisionApply.getExpression().add(new ObjectFactory().createApply(getInnerDecisionApply(value2)));
+					condition.setExpression(new ObjectFactory().createApply(decisionApply));
+					isCompound = true;
+				}
+
+				// if rule algorithm not a compound
+				if (!isCompound) {
+					condition.setExpression(new ObjectFactory().createApply(getInnerDecisionApply(dynamicLabelRuleAlgorithms.get(index).toString())));
+				}
+			}
+			if (!permitRule) {
+				ApplyType notOuterApply = new ApplyType();
+				notOuterApply.setFunctionId(FUNCTION_NOT);
+				notOuterApply.getExpression().add(condition.getExpression());
+				condition.setExpression(new ObjectFactory().createApply(notOuterApply));
+			}
+			rule.setCondition(condition);
+			allOfInRule.getMatch().add(accessMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+
+			decisionPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(decisionPolicy);
+			
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Unsupported data object."+ policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Unsupported data object."+ policyAdapter.getData().getClass().getCanonicalName());
+		}
+
+	}
+	
+	// if compound setting the inner apply here
+	protected ApplyType getInnerDecisionApply(String value1Label) {
+		ApplyType decisionApply = new ApplyType();
+		int index = 0;
+		// check the index for the label.
+		for (String labelAttr : dynamicLabelRuleAlgorithms) {
+			if (labelAttr.equals(value1Label)) {
+				String value1 = (String) dynamicFieldOneRuleAlgorithms.get(index).toString();
+				populateDataTypeList(value1);
+
+				// check if the row contains label again
+				for (String labelValue : dynamicLabelRuleAlgorithms) {
+					if (labelValue.equals(value1)) {
+						return getCompoundDecisionApply(index);
+					}
+				}
+
+				// Getting the values from the form.
+				String functionKey = (String) dynamicFieldComboRuleAlgorithms.get(index).toString();
+				String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+				decisionApply.setFunctionId(dropDownMap.get(functionKey));
+				// if two text field are rule attributes.
+				if ((value1.contains(RULE_VARIABLE)) && (value2.contains(RULE_VARIABLE))) {
+					ApplyType innerDecisionApply1 = new ApplyType();
+					ApplyType	innerDecisionApply2	 = new  ApplyType();							  
+					AttributeDesignatorType  attributeDesignator1	  = new AttributeDesignatorType();								 
+					AttributeDesignatorType  attributeDesignator2	  = new AttributeDesignatorType();											 
+					//If selected function is Integer function set integer functionID
+					if(functionKey.toLowerCase().contains("integer")){
+						innerDecisionApply1.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY );
+						innerDecisionApply2.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY);
+						attributeDesignator1.setDataType(INTEGER_DATATYPE);
+						attributeDesignator2.setDataType(INTEGER_DATATYPE);
+					} else{
+						//If selected function is not a Integer function set String functionID
+						innerDecisionApply1.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+						innerDecisionApply2.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+						attributeDesignator1.setDataType(STRING_DATATYPE);
+						attributeDesignator2.setDataType(STRING_DATATYPE);
+					}
+					attributeDesignator1.setCategory(CATEGORY_RESOURCE);
+					attributeDesignator2.setCategory(CATEGORY_RESOURCE);
+					//Here set actual field values
+					attributeDesignator1.setAttributeId(value1.  contains("resource:")?value1.substring( 9):value1.substring(8));
+					attributeDesignator2.setAttributeId(value1.  contains("resource:")?value1.substring( 9):value1.substring(8));							 
+					innerDecisionApply1.getExpression().add(new ObjectFactory().createAttributeDesignator( attributeDesignator1));
+					innerDecisionApply2.getExpression().add(new ObjectFactory().createAttributeDesignator( attributeDesignator2));							  
+					decisionApply.getExpression().add(new ObjectFactory().createApply(innerDecisionApply1));
+					decisionApply.getExpression().add(new ObjectFactory().createApply(innerDecisionApply2));							  
+				} else {
+					// if either of one text field is rule attribute.
+					if (!value1.startsWith("S_")) {
+						ApplyType innerDecisionApply = new ApplyType();
+						AttributeDesignatorType attributeDesignator = new AttributeDesignatorType();
+						AttributeValueType decisionConditionAttributeValue = new AttributeValueType();
+
+						if (functionKey.toLowerCase().contains("integer")) {
+							innerDecisionApply.setFunctionId(FUNTION_INTEGER_ONE_AND_ONLY);
+							decisionConditionAttributeValue.setDataType(INTEGER_DATATYPE);
+							attributeDesignator.setDataType(INTEGER_DATATYPE);
+						} else {
+							innerDecisionApply.setFunctionId(FUNCTION_STRING_ONE_AND_ONLY);
+							decisionConditionAttributeValue.setDataType(STRING_DATATYPE);
+							attributeDesignator.setDataType(STRING_DATATYPE);
+						}
+
+						String attributeId = null;
+						String attributeValue = null;
+
+						// Find which textField has rule attribute and set it as
+						// attributeId and the other as attributeValue.
+						attributeId = value1;
+						attributeValue = value2;
+			
+						if (attributeId != null) {
+							attributeDesignator.setCategory(CATEGORY_RESOURCE);
+							attributeDesignator.setAttributeId(attributeId);
+						}
+						decisionConditionAttributeValue.getContent().add(attributeValue);
+						innerDecisionApply.getExpression().add(new ObjectFactory().createAttributeDesignator(attributeDesignator));
+						decisionApply.getExpression().add(new ObjectFactory().createAttributeValue(decisionConditionAttributeValue));
+						decisionApply.getExpression().add(new ObjectFactory().createApply(innerDecisionApply));
+					} else {
+						value1 = value1.substring(2, value1.length());
+						VariableReferenceType variableReferenceType = new VariableReferenceType();
+						variableReferenceType.setVariableId(value1);
+						
+						String dataType = dataTypeList.get(index);
+
+						AttributeValueType decisionConditionAttributeValue = new AttributeValueType();
+						decisionConditionAttributeValue.setDataType(dataType);
+						decisionConditionAttributeValue.getContent().add(value2);
+						decisionApply.getExpression().add(new ObjectFactory().createVariableReference(variableReferenceType));
+						decisionApply.getExpression().add(new ObjectFactory().createAttributeValue(decisionConditionAttributeValue));
+					}
+				}
+			}
+			index++;
+		}
+		return decisionApply;
+	}
+
+	// if the rule algorithm is multiple compound one setting the apply
+	protected ApplyType getCompoundDecisionApply(int index) {
+		ApplyType decisionApply = new ApplyType();
+		String selectedFunction = dynamicFieldComboRuleAlgorithms.get(index).toString();
+		String value1 = dynamicFieldOneRuleAlgorithms.get(index).toString();
+		String value2 = dynamicFieldTwoRuleAlgorithms.get(index).toString();
+		decisionApply.setFunctionId(dropDownMap.get(selectedFunction));
+		decisionApply.getExpression().add(new ObjectFactory().createApply(getInnerDecisionApply(value1)));
+		decisionApply.getExpression().add(new ObjectFactory().createApply(getInnerDecisionApply(value2)));
+		return decisionApply;
+	}
+	
+	private VariableDefinitionType createDynamicVariable(String key, String value, String dataType) {
+		VariableDefinitionType dynamicVariable = new VariableDefinitionType();
+		AttributeValueType dynamicAttributeValue = new AttributeValueType();
+
+		dynamicAttributeValue.setDataType(dataType);
+		dynamicAttributeValue.getContent().add(value);
+
+		dynamicVariable.setVariableId(key);
+		dynamicVariable.setExpression(new ObjectFactory().createAttributeValue(dynamicAttributeValue));
+
+		return dynamicVariable;
+
+	}	
+	
+	private void populateDataTypeList(String value1) {
+		
+		///String value1 = dynamicFieldDecisionOneRuleAlgorithms.get(index).getValue().toString();
+		String dataType = null;
+
+		if(value1.contains("S_")) {
+			value1 = value1.substring(2, value1.length());
+			DecisionSettings decisionSettings = findDecisionSettingsBySettingId(value1);
+			if (decisionSettings != null && decisionSettings.getDatatypeBean().getShortName().equals("string")) {
+				dataType = STRING_DATATYPE;
+			} else if (decisionSettings != null && decisionSettings.getDatatypeBean().getShortName().equals("boolean")) {
+				dataType = BOOLEAN_DATATYPE;
+			} else {
+				dataType = INTEGER_DATATYPE;
+			}
+		} else {
+			dataType = "OTHER";
+		}
+
+		dataTypeList.add(dataType);
+	}
+	
+	private Map<String,String> createDropDownMap(){
+		JPAUtils jpaUtils = null;
+		try {
+			jpaUtils = JPAUtils.getJPAUtilsInstance(policyAdapter.getEntityManagerFactory());
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		Map<Datatype, List<FunctionDefinition>> functionMap = jpaUtils.getFunctionDatatypeMap();
+		Map<String, String> dropDownMap = new HashMap<String, String>();
+		for (Datatype id : functionMap.keySet()) {
+			List<FunctionDefinition> functionDefinitions = (List<FunctionDefinition>) functionMap
+					.get(id);
+			for (FunctionDefinition functionDef : functionDefinitions) {
+				dropDownMap.put(functionDef.getShortname(),functionDef.getXacmlid());
+			}
+		}
+		
+		return dropDownMap;
+	}
+	
+	private String getDataType(String key) {
+		
+		DecisionSettings decisionSettings = findDecisionSettingsBySettingId(key);
+		String dataType = null;
+		
+		if (decisionSettings != null && decisionSettings.getDatatypeBean().getShortName().equals("string")) {
+			dataType = STRING_DATATYPE;
+		} else if (decisionSettings != null && decisionSettings.getDatatypeBean().getShortName().equals("boolean")) {
+			dataType = BOOLEAN_DATATYPE;
+		} else {
+			dataType = INTEGER_DATATYPE;
+		}
+		
+		return dataType;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getData();
+	}
+
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/FirewallConfigPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/FirewallConfigPolicy.java
new file mode 100644
index 0000000..ad7525b
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/FirewallConfigPolicy.java
@@ -0,0 +1,1871 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.rest.XACMLRestProperties;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.fge.jackson.JsonLoader;
+import com.github.fge.jsonpatch.JsonPatch;
+import com.github.fge.jsonpatch.diff.JsonDiff;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class FirewallConfigPolicy extends Policy {
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(FirewallConfigPolicy.class);
+
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+	
+	/*
+	 * These are the parameters needed for DB access from the PAP
+	 */
+	private static String papDbDriver = null;
+	private static String papDbUrl = null;
+	private static String papDbUser = null;
+	private static String papDbPassword = null;
+
+	public FirewallConfigPolicy() {
+		super();
+	}
+	
+	public FirewallConfigPolicy(PolicyRestAdapter policyAdapter) {
+		this.policyAdapter = policyAdapter;
+		this.policyAdapter.setConfigType(policyAdapter.getConfigType());
+		
+	}
+	
+	// Saving the Configurations file at server location for config policy.
+	protected void saveConfigurations(String policyName, String prevPolicyName, String jsonBody) {
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		logger.info("print the main domain value"+policyDir);
+		String path = policyDir.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		
+		try {
+			String configFileName = getConfigFile(policyName);
+			
+			File file;
+			if(CONFIG_HOME.contains("\\"))
+			{
+			 file = new File(CONFIG_HOME + "\\" + path + "."+ configFileName);
+			}
+			else
+			{
+			 file = new File(CONFIG_HOME + "/" + path + "."+ configFileName);
+			}
+			
+			// if file doesnt exists, then create it
+			if (!file.exists()) {
+				file.createNewFile();
+			}
+			
+			//Getting the previous policy Config Json file to be used for updating the dictionary tables
+			if (policyAdapter.isEditPolicy()) {
+				
+				String prevConfigFileName = getConfigFile(prevPolicyName);
+				
+				File oldFile;
+				if(CONFIG_HOME.contains("\\"))
+				{
+					oldFile = new File(CONFIG_HOME + "\\" + path + "."+ prevConfigFileName);
+				}
+				else
+				{
+					oldFile = new File(CONFIG_HOME + "/" + path + "."+ prevConfigFileName);
+				}
+				
+				String filepath = oldFile.toString();
+				
+				String prevJsonBody = readFile(filepath, StandardCharsets.UTF_8);
+				policyAdapter.setPrevJsonBody(prevJsonBody);
+			}
+
+
+			File configHomeDir = new File(CONFIG_HOME);
+			File[] listOfFiles = configHomeDir.listFiles();
+			if (listOfFiles != null){
+				for(File eachFile : listOfFiles){
+					if(eachFile.isFile()){
+						String fileNameWithoutExtension = FilenameUtils.removeExtension(eachFile.getName());
+						String configFileNameWithoutExtension = FilenameUtils.removeExtension(configFileName);
+						if (fileNameWithoutExtension.equals(configFileNameWithoutExtension)){
+							//delete the file
+							eachFile.delete();
+						}
+					}
+				}
+			}
+
+			FileWriter fw = new FileWriter(file.getAbsoluteFile());
+			BufferedWriter bw = new BufferedWriter(fw);
+			bw.write(jsonBody);
+			bw.close();
+			if (logger.isDebugEnabled()) {
+				logger.debug("Configuration is succesfully saved");
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	//Utility to read json data from the existing file to a string
+	static String readFile(String path, Charset encoding) throws IOException {
+		
+		byte[] encoded = Files.readAllBytes(Paths.get(path));
+		return new String(encoded, encoding);
+		
+	}
+
+	// Here we are adding the extension for the configurations file based on the
+	// config type selection for saving.
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".json")) {
+			filename = filename.substring(0, filename.length() - 4);
+		}
+
+		filename=filename+".json";
+		return filename;
+	}
+	
+	
+	// Validations for Config form
+	public boolean validateConfigForm() {
+
+		// Validating mandatory Fields.
+		isValidForm = true;	
+		return isValidForm;
+
+	}
+
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			prepareToSave();
+		}
+		
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		Boolean dbIsUpdated = false;
+		if (policyAdapter.getApiflag().equalsIgnoreCase("admin")){
+			dbIsUpdated = true;
+		} else {
+			if (policyAdapter.isEditPolicy()) {
+				dbIsUpdated = updateFirewallDictionaryData(policyAdapter.getJsonBody(), policyAdapter.getPrevJsonBody());
+			} else {
+				dbIsUpdated = insertFirewallDicionaryData(policyAdapter.getJsonBody());
+			}
+		}
+		
+		if(dbIsUpdated) {
+			successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject() );	
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Failed to Update the Database Dictionary Tables.");
+			PolicyLogger.error("Failed to Update the Database Dictionary Tables.");
+			
+			//remove the new json file 
+			String jsonBody = policyAdapter.getPrevJsonBody();
+			if (jsonBody!=null){
+				saveConfigurations(policyName, "", jsonBody);
+			} else {
+				saveConfigurations(policyName, "", "");
+			}
+			successMap.put("fwdberror", "DB UPDATE");
+		}
+
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+		
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+
+		if (policyAdapter.getData() != null) {
+	
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			String prevPolicyName = null;
+			if(policyAdapter.isEditPolicy()){
+				prevPolicyName = "Config_FW_" + policyAdapter.getPolicyName() + "." + policyAdapter.getHighestVersion() + ".xml";
+			}
+
+			Path newFile = getNextFilename(Paths.get(policyAdapter.getParentPath().toString()),
+					(policyAdapter.getPolicyType() + "_FW"), policyAdapter.getPolicyName(), version);
+
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy already Exists, cannot create the policy.");
+				PolicyLogger.error("Policy already Exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			policyName = newFile.getFileName().toString();
+
+			String jsonBody = policyAdapter.getJsonBody();
+			saveConfigurations(policyName, prevPolicyName, jsonBody);
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+			
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+
+			AllOfType allOfOne = new AllOfType();
+			File policyFilePath = new File(policyAdapter.getParentPath().toString(), policyName);
+			String policyDir = policyFilePath.getParentFile().getName();
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = policyDir + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			AllOfType allOf = new AllOfType();
+			
+			// Match for ConfigName
+			allOf.getMatch().add(createMatch("ConfigName", policyAdapter.getConfigName()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+			
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "FirewallConfigPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+			
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+			
+			configAttributeValue.getContent().add("Config");
+			
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "FirewallConfigPolicy", "Exception creating Config URI");
+			}
+			
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+			
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		
+		//Firewall Config ID Assignment
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("firewallConfigID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		
+		// For Config file Url if configurations are provided.
+		//URL ID Assignment
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value"+policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" +path);
+		}		
+		String content = CONFIG_URL + "/Config/" + path + "." + getConfigFile(policyName);
+
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory().createAttributeValue(AttributeValue));
+		advice.getAttributeAssignmentExpression().add(assignment2);
+		
+		//Policy Name Assignment
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+			}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		System.out.println(fileName);
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+		}
+		System.out.println(name);
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+		
+		//Version Number Assignment
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+		advice.getAttributeAssignmentExpression().add(assignment4);
+		
+		//Ecomp Name Assignment
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+		advice.getAttributeAssignmentExpression().add(assignment5);
+		
+		//Config Name Assignment
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("matching:" + this.CONFIGID);
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getConfigName());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+		advice.getAttributeAssignmentExpression().add(assignment6);
+
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+		assignment7.setAttributeId("RiskType");
+		assignment7.setCategory(CATEGORY_RESOURCE);
+		assignment7.setIssuer("");
+
+		AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+		configNameAttributeValue7.setDataType(STRING_DATATYPE);
+		configNameAttributeValue7.getContent().add(policyAdapter.getRiskType());
+		assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+		advice.getAttributeAssignmentExpression().add(assignment7);
+				
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("RiskLevel");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getRiskLevel());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);	
+
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("guard");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getGuard());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);
+				
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("TTLDate");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getTtlDate());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+		
+		int index = 0;
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+	
+	
+	private Boolean insertFirewallDicionaryData (String jsonBody) throws SQLException {
+
+		
+		JsonObject json = null;
+		if (jsonBody != null) {
+			
+			//Read jsonBody to JsonObject
+			json = stringToJson(jsonBody);
+			
+			JsonArray firewallRules = null;
+			JsonArray serviceGroup = null;
+			JsonArray addressGroup = null;
+			String securityZone=null;
+			
+			Connection con = null;
+			Statement st = null;
+			ResultSet rs = null;
+			
+			/*
+			 * Retrieve the property values for db access from the xacml.pap.properties
+			 */
+			papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
+			papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
+			papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
+			papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
+
+			//insert data into tables
+			try {
+				//Get DB Connection
+				Class.forName(papDbDriver);
+				con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
+				st = con.createStatement();
+				
+				firewallRules = json.getJsonArray("firewallRuleList");
+				serviceGroup = json.getJsonArray("serviceGroups");
+				addressGroup = json.getJsonArray("addressGroups");	
+				securityZone=json.getString("primaryParentZoneId").toString();
+				
+				logger.info("Parent child: securityZone from JSON: "+securityZone);
+				String insertQuery = null;
+				
+				//Inserting childPolicy and its parent to the FWChildToParent DB table
+				if(securityZone!=null){
+					//Its a child Policy. 
+					//Retrieve the parent name from the securityZone Id
+					String retrieveParentQuery= "select parent from fwparent where securityZone='";
+					
+					retrieveParentQuery=retrieveParentQuery+securityZone+"';";
+					logger.info("Parent child: Query to retrieve parent "+retrieveParentQuery);
+					rs = st.executeQuery(retrieveParentQuery);
+					
+					String parent=null;
+					if(rs.next()){
+						parent = rs.getString("parent");
+					}
+					rs.close();
+					
+					
+					String insertQueryChildTable="INSERT INTO FWChildToParent(child, parent) VALUES ('";
+					insertQueryChildTable=insertQueryChildTable+policyAdapter.getPolicyName()+"','"+parent+"');";
+					logger.info("Parent child: Insert child and parent to DB: "+insertQueryChildTable);
+					st.executeUpdate(insertQueryChildTable);
+					
+				}
+				
+				/*
+				 * Inserting firewallRuleList data into the Terms, SecurityZone, and Action tables
+				 */
+				if (firewallRules != null) {
+					
+					int termID = 0;
+					int zoneID = 0;
+					int actionID = 0;
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM TERM;");
+					if(rs.next()){
+						termID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ZONE;");
+					if(rs.next()){
+						zoneID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ACTIONLIST;");
+					if(rs.next()){
+						actionID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					int i = 0;
+					for(JsonValue jsonValue : firewallRules) {
+						
+						//increment ID Primary Keys
+						termID = termID + 1;
+						zoneID = zoneID + 1;
+						actionID = actionID + 1;
+						
+						/*
+						 * Populate ArrayLists with values from the JSON
+						 */
+						//create the JSON object from the JSON Array for each iteration through the for loop
+						JsonObject ruleListobj = firewallRules.getJsonObject(i);
+												
+						//get values from JSON fields of firewallRulesList Array
+						String ruleName = ruleListobj.get("ruleName").toString();
+						String action = ruleListobj.get("action").toString();
+						String description = ruleListobj.get("description").toString();
+						
+						rs = st.executeQuery("SELECT * FROM TERM WHERE TERMNAME = "+ ruleName + ";");
+						
+						if (rs.next()) {
+							st.executeUpdate("DELETE FROM TERM WHERE TERMNAME = "+ ruleName + ";");
+						}
+						rs.close();
+						
+						//getting fromZone Array field from the firewallRulesList
+						JsonArray fromZoneArray = ruleListobj.getJsonArray("fromZones");
+						String fromZoneString = null;
+						
+						int fromZoneIndex = 0;
+						for (JsonValue fromZoneJsonValue : fromZoneArray) {
+							String value = fromZoneArray.get(fromZoneIndex).toString();
+							value = value.replace("\"", "");
+							
+							if (fromZoneString != null) {
+								fromZoneString = fromZoneString.concat(",").concat(value);
+								
+							} else {
+								fromZoneString = value;
+							}
+							
+							fromZoneIndex++;
+							
+						}
+						String fromZoneInsert = "'"+fromZoneString+"'";
+						
+						//getting toZone Array field from the firewallRulesList
+						JsonArray toZoneArray = ruleListobj.getJsonArray("toZones");
+						String toZoneString = null;
+						
+						int toZoneIndex = 0;
+						for (JsonValue toZoneJsonValue : toZoneArray) {
+							String value = toZoneArray.get(toZoneIndex).toString();
+							value = value.replace("\"", "");
+							
+							if (toZoneString != null) {
+								toZoneString = toZoneString.concat(",").concat(value);
+								
+							} else {
+								toZoneString = value;
+							}
+							
+							toZoneIndex++;
+							
+						}
+						String toZoneInsert = "'"+toZoneString+"'";
+						
+						//getting sourceList Array fields from the firewallRulesList
+						JsonArray srcListArray = ruleListobj.getJsonArray("sourceList");
+						String srcListString = null;
+						
+						int srcListIndex = 0;
+						for (JsonValue srcListJsonValue : srcListArray) {
+							JsonObject srcListObj = srcListArray.getJsonObject(srcListIndex);
+							String type = srcListObj.get("type").toString().replace("\"", "");
+							
+							String value = null;
+							if(type.equals("REFERENCE")||type.equals("GROUP")){
+								value = srcListObj.get("name").toString();
+							} else if (type.equalsIgnoreCase("ANY")){
+								value = null;
+							} else {
+								value = srcListObj.get("value").toString();
+							}
+							
+							if (value!=null){
+								value = value.replace("\"", "");
+							}
+							
+							if (srcListString != null) {
+								srcListString = srcListString.concat(",").concat(value);
+								
+							} else {
+								srcListString = value;
+							}
+							
+							srcListIndex++;
+							
+						}
+						String srcListInsert = "'"+srcListString+"'";
+						
+						//getting destinationList Array fields from the firewallRulesList
+						JsonArray destListArray = ruleListobj.getJsonArray("destinationList");
+						String destListString = null;
+						
+						int destListIndex = 0;
+						for (JsonValue destListJsonValue : destListArray) {
+							JsonObject destListObj = destListArray.getJsonObject(destListIndex);
+							String type = destListObj.get("type").toString().replace("\"", "");
+							
+							String value = null;
+							if(type.equals("REFERENCE")||type.equals("GROUP")){
+								value = destListObj.get("name").toString();
+							} else if (type.equalsIgnoreCase("ANY")){
+								value = null;
+							} else {
+								value = destListObj.get("value").toString();
+							}
+							
+							if (value!=null){
+								value = value.replace("\"", "");
+							}
+							
+							if (destListString != null) {
+								destListString = destListString.concat(",").concat(value);
+							} else {
+								destListString = value;
+							}
+							
+							destListIndex++;
+						}
+						String destListInsert = "'"+destListString+"'";
+						
+						//getting destServices Array fields from the firewallRulesList
+						JsonArray destServicesArray = ruleListobj.getJsonArray("destServices");
+						String destPortListString = null;
+						
+						int destPortListIndex = 0;
+						for (JsonValue destListJsonValue : destServicesArray) {
+							JsonObject destServicesObj = destServicesArray.getJsonObject(destPortListIndex);
+							String type = destServicesObj.get("type").toString().replace("\"", "");
+							
+							String value = null;
+							if(type.equals("REFERENCE")||type.equals("GROUP")){
+								value = destServicesObj.get("name").toString();
+							} else if (type.equalsIgnoreCase("ANY")){
+								value = null;
+							} else {
+								value = destServicesObj.get("value").toString();
+							}
+							
+							if (value!=null){
+								value = value.replace("\"", "");
+							}
+							
+							if (destPortListString != null) {
+								destPortListString = destPortListString.concat(",").concat(value);
+							} else {
+								destPortListString = value;
+							}
+							
+							destPortListIndex++;
+						}
+						String destPortListInsert = "'"+destPortListString+"'";					
+						
+						/*
+						 * Create Queries to INSERT data into database tables and execute 
+						 */					
+                        String termSql = "INSERT INTO Term (ID, TERMNAME, SRCIPLIST, DESTIPLIST, PROTOCOLLIST, PORTLIST, SRCPORTLIST,"
+                                 + " DESTPORTLIST, ACTION, DESCRIPTION, FROMZONE, TOZONE, CREATED_BY, MODIFIED_DATE) VALUES ("+termID+","
+                                 +ruleName+","+srcListInsert+","+destListInsert+","+ "null"+","+"null"+","+"null"+","+destPortListInsert+","
+                                 +action+","+description+","+fromZoneInsert+","+toZoneInsert+",'API',"+ "null"+ "); ";
+						termSql = termSql.replace('"', '\'');
+						st.addBatch(termSql);
+
+						String actionSql = "INSERT INTO ACTIONLIST (ID, ACTIONNAME, DESCRIPTION) VALUES ("+actionID+","+action+","+action+"); ";
+						actionSql = actionSql.replace('"', '\'');
+						st.addBatch(actionSql);
+						
+						st.executeBatch();
+						
+						i++;
+					}
+					
+				}
+				
+				/*
+				 * Inserting serviceGroups data into the ServiceGroup, ServiceList, ProtocolList, and PortList tables
+				 */
+				if (serviceGroup != null) {
+					
+					int serviceGroupID = 0;
+					int serviceListID = 0;
+					int protocolID = 0;
+					int portID = 0;
+
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM SERVICEGROUP;");
+					if(rs.next()){
+						serviceGroupID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM GROUPSERVICELIST;");
+					if(rs.next()){
+						serviceListID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PROTOCOLLIST;");
+					if(rs.next()){
+						protocolID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PORTLIST;");
+					if(rs.next()){
+						portID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					int i = 0;
+					for(JsonValue jsonValue : serviceGroup) {
+						
+						/*
+						 * Populate ArrayLists with values from the JSON
+						 */
+						//create the JSON object from the JSON Array for each iteration through the for loop
+						JsonObject svcGroupListobj = serviceGroup.getJsonObject(i);
+												
+						String serviceListName = svcGroupListobj.get("name").toString();
+						
+						String description = null;
+						if (svcGroupListobj.containsKey("description")){
+							description = svcGroupListobj.get("description").toString();
+						}
+						
+						//getting members Array from the serviceGroup
+						JsonArray membersArray = svcGroupListobj.getJsonArray("members");
+
+						//String type = svcGroupListobj.get("type").toString();
+						Boolean isServiceGroup = false;
+						if (membersArray!=null){
+							String membersType = membersArray.getJsonObject(0).get("type").toString();
+							if (membersType.contains("REFERENCE")) {
+								isServiceGroup = true;
+							}
+						}
+												
+						//Insert values into GROUPSERVICELIST table if name begins with Group 
+						if (isServiceGroup) {
+							
+							//increment ID Primary Keys
+							serviceListID = serviceListID + 1;
+
+							String name = null;
+							
+							int membersIndex = 0;
+							for (JsonValue membersValue : membersArray) {
+								JsonObject membersObj = membersArray.getJsonObject(membersIndex);
+								//String value = membersObj.get("name").toString();
+								String type = membersObj.get("type").toString().replace("\"", "");
+								
+								String value = null;
+								if(type.equals("REFERENCE")||type.equals("GROUP")||type.equals("SERVICE")){
+									value = membersObj.get("name").toString();
+								} else if (type.equalsIgnoreCase("ANY")){
+									value = null;
+								} else {
+									value = membersObj.get("value").toString();
+								}
+								
+								if(value != null){
+									value = value.replace("\"", "");
+								}
+								
+								if (name != null) {
+									name = name.concat(",").concat(value);
+								} else {
+									name = value;
+								}
+								
+								membersIndex++;
+							}
+							String nameInsert = "'"+name+"'";		
+							
+							insertQuery = "INSERT INTO GROUPSERVICELIST (ID, NAME, SERVICELIST) "
+									+ "VALUES("+serviceListID+","+serviceListName+","+nameInsert+")";
+							
+							//Replace double quote with single quote
+							insertQuery = insertQuery.replace('"', '\'');
+							
+							//Execute the queries to Insert data
+				            st.executeUpdate(insertQuery);
+													
+						} else { //Insert JSON data serviceList table, protollist table, and portlist table
+
+							//increment ID Primary Keys
+							protocolID = protocolID + 1;
+							portID = portID + 1;
+							serviceGroupID = serviceGroupID + 1;
+							
+							String type = svcGroupListobj.get("type").toString();
+							String transportProtocol = svcGroupListobj.get("transportProtocol").toString();
+							String ports = svcGroupListobj.get("ports").toString();
+							
+							/*
+							 * Create Queries to INSERT data into database table and execute 
+							 */
+							String serviceSql = "INSERT INTO SERVICEGROUP (ID, NAME, DESCRIPTION, TYPE, TRANSPORTPROTOCOL, APPPROTOCOL, PORTS) "
+									+ "VALUES("+serviceGroupID+","+serviceListName+","+description+","+type+","
+									+ transportProtocol+","+"null,"+ports+"); ";
+							serviceSql = serviceSql.replace('"', '\'');
+							st.addBatch(serviceSql);
+							
+							String protSql = "INSERT INTO PROTOCOLLIST (ID, PROTOCOLNAME, DESCRIPTION) VALUES("+protocolID+","+transportProtocol+","+transportProtocol+"); ";
+							protSql = protSql.replace('"', '\'');
+							st.addBatch(protSql);
+							
+							String portSql = "INSERT INTO PORTLIST (ID, PORTNAME, DESCRIPTION) VALUES("+portID+","+ports+","+ports+");";
+							portSql = portSql.replace('"', '\'');
+							st.addBatch(portSql);
+							
+							st.executeBatch();
+
+						}		
+						
+						
+						
+						i++;
+					}
+				}
+				
+				/*
+				 * Inserting addressGroup data into the ADDRESSGROUP table
+				 */
+				if (addressGroup != null) {
+					int prefixID = 0;
+					int addressID = 0;
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PREFIXLIST;");
+					if(rs.next()){
+						prefixID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ADDRESSGROUP;");
+					if(rs.next()){
+						addressID = rs.getInt("ID");
+					}
+					rs.close();
+					
+					
+					int i = 0;
+					for(JsonValue jsonValue : addressGroup) {
+						
+						/*
+						 * Populate ArrayLists with values from the JSON
+						 */
+						//create the JSON object from the JSON Array for each iteration through the for loop
+						JsonObject addressGroupObj = addressGroup.getJsonObject(i);
+						
+						//create JSON array for members
+						JsonArray membersArray = addressGroupObj.getJsonArray("members");
+						String addressGroupName = addressGroupObj.get("name").toString();
+						
+						String description = null;
+						if (addressGroupObj.containsKey("description")){
+							description = addressGroupObj.get("description").toString();
+						}
+						
+						String prefixIP = null;
+						String type = null;
+						
+						int membersIndex = 0;
+						for (JsonValue membersValue : membersArray) {
+							JsonObject membersObj = membersArray.getJsonObject(membersIndex);
+							//String value = membersObj.get("value").toString();
+							type = membersObj.get("type").toString().replace("\"", "");
+							
+							String value = null;
+							if(type.equals("REFERENCE")||type.equals("GROUP")||type.equals("SERVICE")){
+								value = membersObj.get("name").toString();
+							} else if (type.equalsIgnoreCase("ANY")){
+								value = null;
+							} else {
+								value = membersObj.get("value").toString();
+							}
+							
+							if(value != null){
+								value = value.replace("\"", "");
+							}
+							
+							if (prefixIP != null) {
+								prefixIP = prefixIP.concat(",").concat(value);
+							} else {
+								prefixIP = value;
+							}
+							
+							membersIndex++;
+						}
+						String prefixList = "'"+prefixIP+"'";
+						
+						Boolean isAddressGroup = type.contains("REFERENCE");
+						
+						if (isAddressGroup) {								
+							//increment ID Primary Keys
+							addressID = addressID + 1;
+							
+							insertQuery = "INSERT INTO ADDRESSGROUP (ID, NAME, DESCRIPTION, PREFIXLIST) "
+										+ "VALUES("+addressID+","+addressGroupName+","+description+","+prefixList+")";	
+						} else {
+							 //increment ID Primary Key
+							prefixID = prefixID + 1;
+							
+							insertQuery = "INSERT INTO PREFIXLIST (ID, PL_NAME, PL_VALUE, DESCRIPTION) "
+										+ "VALUES("+prefixID+","+addressGroupName+","+prefixList+","+description+")";
+							
+						}
+		
+						
+						//Replace double quote with single quote
+						insertQuery = insertQuery.replace('"', '\'');
+						
+						//Execute the queries to Insert data
+			            st.executeUpdate(insertQuery);
+						
+						i++;
+					}
+					
+				}
+				
+				/*
+				 * Remove duplicate values from 'lookup' dictionary tables
+				 */
+				//ProtocolList Table
+				String protoDelete = "DELETE FROM protocollist USING protocollist, protocollist p1 "
+						+ "WHERE protocollist.id > p1.id AND protocollist.protocolname = p1.protocolname;";
+				st.addBatch(protoDelete);
+				
+				//PortList Table
+				String portListDelete = "DELETE FROM portlist USING portlist, portlist p1 "
+						+ "WHERE portlist.id > p1.id AND portlist.portname = p1.portname; ";
+				st.addBatch(portListDelete);
+				
+				//PrefixList Table
+				String prefixListDelete = "DELETE FROM prefixlist USING prefixlist, prefixlist p1 "
+						+ "WHERE prefixlist.id > p1.id AND prefixlist.pl_name = p1.pl_name AND "
+						+ "prefixlist.pl_value = p1.pl_value AND prefixlist.description = p1.description; ";
+				st.addBatch(prefixListDelete);
+				
+				//GroupServiceList
+				String groupServiceDelete = "DELETE FROM groupservicelist USING groupservicelist, groupservicelist g1 "
+						+ "WHERE groupservicelist.id > g1.id AND groupservicelist.name = g1.name AND "
+						+ "groupservicelist.serviceList = g1.serviceList; ";
+				st.addBatch(groupServiceDelete);
+				
+				st.executeBatch();
+				
+			} catch (ClassNotFoundException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "FirewallConfigPolicy", "Exception building Firewall queries ");
+				System.out.println(e.getMessage());
+				return false;
+	
+			} catch (SQLException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "FirewallConfigPolicy", "Exception executing Firewall queries");
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "FirewallConfigPolicy", "Exception getting Json values");
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				try{
+					if (con!=null) con.close();
+					if (rs!=null) rs.close();
+					if (st!=null) st.close();
+				} catch (Exception ex){}
+			}
+			return true;
+
+		} else {
+			return false;
+		}
+		
+	}
+
+
+	private Boolean updateFirewallDictionaryData(String jsonBody, String prevJsonBody) {
+		
+		JsonObject oldJson = null;
+		JsonObject newJson = null;
+		
+		if (jsonBody != null || prevJsonBody != null) {
+			
+			oldJson = stringToJson(prevJsonBody);
+			newJson = stringToJson(jsonBody);
+			
+			//if no changes to the json then return true
+			if (oldJson.equals(newJson)) {
+				return true;
+			}
+			
+			JsonArray firewallRules = null;
+			JsonArray serviceGroup = null;
+			JsonArray addressGroup = null;
+			
+			firewallRules = newJson.getJsonArray("firewallRuleList");
+			serviceGroup = newJson.getJsonArray("serviceGroups");
+			addressGroup = newJson.getJsonArray("addressGroups");	
+			
+			Connection con = null;
+			Statement st = null;
+			ResultSet rs = null;
+			
+			/*
+			 * Retrieve the property values for db access from the xacml.pap.properties
+			 */
+			papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
+			papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
+			papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
+			papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
+	
+			//insert data into tables
+			try {
+				
+				//Get DB Connection
+				Class.forName(papDbDriver);
+				con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
+				st = con.createStatement();
+				
+				JsonNode jsonDiff = createPatch(jsonBody, prevJsonBody);
+				
+				int i = 0;
+				for (JsonNode node : jsonDiff) {
+					//String path = jsonDiff.get(i).asText();
+					String jsonpatch = jsonDiff.get(i).toString();
+					
+					JsonObject patchObj = stringToJson(jsonpatch);
+					
+					String path = patchObj.get("path").toString().replace('"', ' ').trim();
+					 					
+					if (path.contains("firewallRuleList")) {
+						int termID = 0;
+						int zoneID = 0;
+						int actionID = 0;
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM TERM;");
+						if(rs.next()){
+							termID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ZONE;");
+						if(rs.next()){
+							zoneID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ACTIONLIST;");
+						if(rs.next()){
+							actionID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						String insertQuery = null;
+						
+						/*
+						 * Inserting firewallRuleList data into the Terms, SecurityZone, and Action tables
+						 */
+						int ri = 0;
+						for(JsonValue jsonValue : firewallRules) {
+							
+							//increment ID Primary Keys
+							termID = termID + 1;
+							zoneID = zoneID + 1;
+							actionID = actionID + 1;
+							
+							/*
+							 * Populate ArrayLists with values from the JSON
+							 */
+							//create the JSON object from the JSON Array for each iteration through the for loop
+							JsonObject ruleListobj = firewallRules.getJsonObject(ri);
+							
+							//get values from JSON fields of firewallRulesList Array
+							String ruleName = ruleListobj.get("ruleName").toString().replace('"', '\'');
+							String action = ruleListobj.get("action").toString().replace('"', '\'');
+							String description = ruleListobj.get("description").toString().replace('"', '\'');
+							
+							rs = st.executeQuery("SELECT * FROM TERM WHERE TERMNAME = "+ ruleName + ";");
+							
+							if (rs.next()) {
+								st.executeUpdate("DELETE FROM TERM WHERE TERMNAME = "+ ruleName + ";");
+							}
+							rs.close();
+							
+							//getting fromZone Array field from the firewallRulesList
+							JsonArray fromZoneArray = ruleListobj.getJsonArray("fromZones");
+							String fromZoneString = null;
+							
+							int fromZoneIndex = 0;
+							for (JsonValue fromZoneJsonValue : fromZoneArray) {
+								String value = fromZoneArray.get(fromZoneIndex).toString();
+								value = value.replace("\"", "");
+								
+								if (fromZoneString != null) {
+									fromZoneString = fromZoneString.concat(",").concat(value);
+									
+								} else {
+									fromZoneString = value;
+								}
+								
+								fromZoneIndex++;
+								
+							}
+							String fromZoneInsert = "'"+fromZoneString+"'";
+							
+							//getting toZone Array field from the firewallRulesList
+							JsonArray toZoneArray = ruleListobj.getJsonArray("toZones");
+							String toZoneString = null;
+							
+							int toZoneIndex = 0;
+							for (JsonValue toZoneJsonValue : toZoneArray) {
+								String value = toZoneArray.get(toZoneIndex).toString();
+								value = value.replace("\"", "");
+								
+								if (toZoneString != null) {
+									toZoneString = toZoneString.concat(",").concat(value);
+									
+								} else {
+									toZoneString = value;
+								}
+								
+								toZoneIndex++;
+								
+							}
+							String toZoneInsert = "'"+toZoneString+"'";
+							//getting sourceList Array fields from the firewallRulesList
+							JsonArray srcListArray = ruleListobj.getJsonArray("sourceList");
+							String srcListString = null;
+							
+							int srcListIndex = 0;
+							for (JsonValue srcListJsonValue : srcListArray) {
+								JsonObject srcListObj = srcListArray.getJsonObject(srcListIndex);
+								String type = srcListObj.get("type").toString().replace("\"", "");
+								
+								String value = null;
+								if(type.equals("REFERENCE")||type.equals("GROUP")){
+									value = srcListObj.get("name").toString();
+								} else if (type.equalsIgnoreCase("ANY")){
+									value = null;
+								} else {
+									value = srcListObj.get("value").toString();
+								}
+								
+								if(value != null){
+									value = value.replace("\"", "");
+								}
+								
+								if (srcListString != null) {
+									srcListString = srcListString.concat(",").concat(value);
+									
+								} else {
+									srcListString = value;
+								}
+								
+								srcListIndex++;
+								
+							}
+							String srcListInsert = "'"+srcListString+"'";
+							
+							//getting destinationList Array fields from the firewallRulesList
+							JsonArray destListArray = ruleListobj.getJsonArray("destinationList");
+							String destListString = null;
+							
+							int destListIndex = 0;
+							for (JsonValue destListJsonValue : destListArray) {
+								JsonObject destListObj = destListArray.getJsonObject(destListIndex);
+								String type = destListObj.get("type").toString().replace("\"", "");
+								
+								String value = null;
+								if(type.equals("REFERENCE")||type.equals("GROUP")){
+									value = destListObj.get("name").toString();
+								} else if (type.equalsIgnoreCase("ANY")){
+									value = null;
+								} else {
+									value = destListObj.get("value").toString();
+								}
+								
+								if(value != null){
+									value = value.replace("\"", "");
+								}
+								
+								if (destListString != null) {
+									destListString = destListString.concat(",").concat(value);
+								} else {
+									destListString = value;
+								}
+								
+								destListIndex++;
+							}
+							String destListInsert = "'"+destListString+"'";
+							
+							//getting destServices Array fields from the firewallRulesList
+							JsonArray destServicesArray = ruleListobj.getJsonArray("destServices");
+							String destPortListString = null;
+							
+							int destPortListIndex = 0;
+							for (JsonValue destListJsonValue : destServicesArray) {
+								JsonObject destServicesObj = destServicesArray.getJsonObject(destPortListIndex);
+								String type = destServicesObj.get("type").toString().replace("\"", "");
+								
+								String value = null;
+								if(type.equals("REFERENCE")||type.equals("GROUP")){
+									value = destServicesObj.get("name").toString();
+								} else if (type.equalsIgnoreCase("ANY")){
+									value = null;
+								} else {
+									value = destServicesObj.get("value").toString();
+								}
+								
+								if(value != null){
+									value = value.replace("\"", "");
+								}
+								
+								if (destPortListString != null) {
+									destPortListString = destPortListString.concat(",").concat(value);
+								} else {
+									destPortListString = value;
+								}
+								
+								destPortListIndex++;
+							}
+							String destPortListInsert = "'"+destPortListString+"'";					
+							
+							/*
+							 * Create Queries to INSERT data into database tables and execute 
+							 */
+							
+							//Insert Into Terms table
+	                        String termSql = "INSERT INTO Term (ID, TERMNAME, SRCIPLIST, DESTIPLIST, PROTOCOLLIST, PORTLIST, SRCPORTLIST,"
+	                                 + " DESTPORTLIST, ACTION, DESCRIPTION, FROMZONE, TOZONE, CREATED_BY, MODIFIED_DATE) VALUES ("+termID+","
+	                                 +ruleName+","+srcListInsert+","+destListInsert+","+ "null"+","+"null"+","+"null"+","+destPortListInsert+","
+	                                 +action+","+description+","+fromZoneInsert+","+toZoneInsert+",'API',"+ "null"+ "); ";
+							
+							termSql = termSql.replace('"', '\'');
+							st.addBatch(termSql);
+							
+							rs = st.executeQuery("SELECT * FROM ACTIONLIST WHERE ACTIONNAME = " + action + ";");
+							
+							String actionSql = null;
+							if (rs.next()) {
+								//do nothing
+							} else {
+								actionSql = "INSERT INTO ACTIONLIST (ID, ACTIONNAME, DESCRIPTION) VALUES ("+actionID+","+action+","+action+") ";
+								actionSql = actionSql.replace('"', '\'');
+								st.addBatch(actionSql);
+							}
+
+							st.executeBatch();
+							
+							ri++;
+						}
+						
+					}
+					
+					if (path.contains("serviceGroups")) {
+						int serviceGroupID = 0;
+						int serviceListID = 0;
+						int protocolID = 0;
+						int portID = 0;
+
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM SERVICEGROUP;");
+						if(rs.next()){
+							serviceGroupID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM GROUPSERVICELIST;");
+						if(rs.next()){
+							serviceListID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PROTOCOLLIST;");
+						if(rs.next()){
+							protocolID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PORTLIST;");
+						if(rs.next()){
+							portID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						String insertQuery = null;
+						
+						/*
+						 * Inserting serviceGroups data into the ServiceGroup, ServiceList, ProtocolList, and PortList tables
+						 */
+						int si = 0;
+						for(JsonValue jsonValue : serviceGroup) {
+							
+							/*
+							 * Populate ArrayLists with values from the JSON
+							 */
+							//create the JSON object from the JSON Array for each iteration through the for loop
+							JsonObject svcGroupListobj = serviceGroup.getJsonObject(si);
+							
+							String groupName = svcGroupListobj.get("name").toString().replace('"', '\''); 
+							
+							String description = null;
+							if (svcGroupListobj.containsKey("description")){
+								description = svcGroupListobj.get("description").toString().replace('"', '\'');
+							}
+							
+							JsonArray membersArray = svcGroupListobj.getJsonArray("members");
+
+							Boolean isServiceGroup = false;
+							if (membersArray!=null){
+								String membersType = membersArray.getJsonObject(0).get("type").toString();
+								if (membersType.contains("REFERENCE")) {
+									isServiceGroup = true;
+								}
+							}
+							
+							//Insert values into GROUPSERVICELIST table if name begins with Group 
+							if (isServiceGroup) {
+								
+								rs = st.executeQuery("SELECT * FROM GROUPSERVICELIST WHERE NAME = "+ groupName + ";");
+								
+								if (rs.next()) {
+									st.executeUpdate("DELETE FROM GROUPSERVICELIST WHERE NAME = "+ groupName + ";");
+								}
+								rs.close();
+								//increment ID Primary Keys
+								serviceListID = serviceListID + 1;
+								
+								String name = null;
+								int membersIndex = 0;
+								for (JsonValue membersValue : membersArray) {
+									JsonObject membersObj = membersArray.getJsonObject(membersIndex);
+									String type = membersObj.get("type").toString().replace("\"", "");
+									
+									String value = null;
+									if(type.equals("REFERENCE")||type.equals("GROUP")||type.equals("SERVICE")){
+										value = membersObj.get("name").toString();
+									} else if (type.equalsIgnoreCase("ANY")){
+										value = null;
+									} else {
+										value = membersObj.get("value").toString();
+									}
+									
+									if(value != null){
+										value = value.replace("\"", "");
+									}
+									
+									if (name != null) {
+										name = name.concat(",").concat(value);
+									} else {
+										name = value;
+									}
+									
+									membersIndex++;
+								}
+								String nameInsert = "'"+name+"'";		
+								
+								insertQuery = "INSERT INTO GROUPSERVICELIST (ID, NAME, SERVICELIST) "
+										+ "VALUES("+serviceListID+","+groupName+","+nameInsert+")";
+								
+								//Replace double quote with single quote
+								insertQuery = insertQuery.replace('"', '\'');
+								
+								//Execute the queries to Insert data
+					            st.executeUpdate(insertQuery);
+														
+							} else { //Insert JSON data serviceGroup table, protocollist table, and portlist table
+																
+								//increment ID Primary Keys
+								protocolID = protocolID + 1;
+								portID = portID + 1;
+								serviceGroupID = serviceGroupID + 1;
+								
+								String type = svcGroupListobj.get("type").toString().replace('"', '\'');
+								String transportProtocol = svcGroupListobj.get("transportProtocol").toString().replace('"', '\'');
+								String ports = svcGroupListobj.get("ports").toString().replace('"', '\'');
+								
+								rs = st.executeQuery("SELECT * FROM SERVICEGROUP WHERE NAME = "+ groupName + ";");
+								
+								if (rs.next()) {
+									st.executeUpdate("DELETE FROM SERVICEGROUP WHERE NAME = "+ groupName + ";");
+								}
+								rs.close();
+								
+								String svcGroupSql = "INSERT INTO SERVICEGROUP (ID, NAME, DESCRIPTION, TYPE, TRANSPORTPROTOCOL, APPPROTOCOL, PORTS) "
+											+ "VALUES("+serviceGroupID+","+groupName+","+description+","+type+","
+											+ transportProtocol+","+"null,"+ports+"); ";
+								svcGroupSql = svcGroupSql.replace('"', '\'');
+								st.addBatch(svcGroupSql);
+								
+								rs = st.executeQuery("SELECT * FROM PROTOCOLLIST WHERE PROTOCOLNAME = " + transportProtocol + ";");
+								
+								String protoSql = null;
+								if (rs.next()) {
+									//do nothing
+								} else {
+									protoSql = "INSERT INTO PROTOCOLLIST (ID, PROTOCOLNAME, DESCRIPTION) "
+											+ "VALUES("+protocolID+","+transportProtocol+","+transportProtocol+"); ";
+									protoSql = protoSql.replace('"', '\'');
+									st.addBatch(protoSql);
+
+								}
+								rs.close();
+
+								rs = st.executeQuery("SELECT * FROM PORTLIST WHERE PORTNAME = " + ports + ";");
+								
+								String portSql = null;
+								if (rs.next()) {
+									//do nothing
+								} else {
+									portSql = "INSERT INTO PORTLIST (ID, PORTNAME, DESCRIPTION) VALUES("+portID+","+ports+","+ports+"); ";
+									portSql = portSql.replace('"', '\'');
+									st.addBatch(portSql);
+								}
+								rs.close();
+								
+								st.executeBatch();
+
+							}		
+							
+							
+				            si++;
+						}
+						
+					}
+					
+					if (path.contains("addressGroups")) {
+						/*
+						 * Inserting addressGroup data into the ADDRESSGROUP table
+						 */
+						int prefixID = 0;
+						int addressID = 0;
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM PREFIXLIST;");
+						if(rs.next()){
+							prefixID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						rs = st.executeQuery("SELECT MAX(ID) AS ID FROM ADDRESSGROUP;");
+						if(rs.next()){
+							addressID = rs.getInt("ID");
+						}
+						rs.close();
+						
+						String insertQuery = null;
+						
+						int ai = 0;
+						for(JsonValue jsonValue : addressGroup) {
+							
+							/*
+							 * Populate ArrayLists with values from the JSON
+							 */
+							//create the JSON object from the JSON Array for each iteration through the for loop
+							JsonObject addressGroupObj = addressGroup.getJsonObject(ai);
+							
+							//create JSON array for members
+							JsonArray membersArray = addressGroupObj.getJsonArray("members");
+							String addressGroupName = addressGroupObj.get("name").toString().replace('"', '\'');
+							
+							String description = null;
+							if (addressGroupObj.containsKey("description")){
+								description = addressGroupObj.get("description").toString().replace('"', '\'');
+							}
+							
+							String prefixIP = null;
+							String type = null;
+							int membersIndex = 0;
+							for (JsonValue membersValue : membersArray) {
+								JsonObject membersObj = membersArray.getJsonObject(membersIndex);
+								type = membersObj.get("type").toString().replace("\"", "");
+								
+								String value = null;
+								if(type.equals("REFERENCE")||type.equals("GROUP")||type.equals("SERVICE")){
+									value = membersObj.get("name").toString();
+								} else if (type.equalsIgnoreCase("ANY")){
+									value = null;
+								} else {
+									value = membersObj.get("value").toString();
+								}
+								
+								if(value != null){
+									value = value.replace("\"", "");
+								}
+								
+								if (prefixIP != null) {
+									prefixIP = prefixIP.concat(",").concat(value);
+								} else {
+									prefixIP = value;
+								}
+								
+								membersIndex++;
+							}
+							String prefixList = "'"+prefixIP+"'";
+							
+							Boolean isAddressGroup = type.contains("REFERENCE");
+							
+							if (isAddressGroup) {		
+								
+								rs = st.executeQuery("SELECT * FROM ADDRESSGROUP WHERE NAME = "+ addressGroupName + ";");
+								
+								if (rs.next()) {
+									st.executeUpdate("DELETE FROM ADDRESSGROUP WHERE NAME = "+ addressGroupName + ";");
+								}
+								rs.close();
+								//increment ID Primary Keys
+								addressID = addressID + 1;
+								
+								insertQuery = "INSERT INTO ADDRESSGROUP (ID, NAME, DESCRIPTION, PREFIXLIST) "
+											+ "VALUES("+addressID+","+addressGroupName+","+description+","+prefixList+")";	
+								
+								
+								
+							} else {
+								
+								rs = st.executeQuery("SELECT * FROM PREFIXLIST WHERE PL_NAME = "+ addressGroupName + ";");
+								
+								if (rs.next()) {
+									st.executeUpdate("DELETE FROM PREFIXLIST WHERE PL_NAME = "+ addressGroupName + ";");
+								}
+								rs.close();
+								 //increment ID Primary Key
+								prefixID = prefixID + 1;
+								
+								insertQuery = "INSERT INTO PREFIXLIST (ID, PL_NAME, PL_VALUE, DESCRIPTION) "
+											+ "VALUES("+prefixID+","+addressGroupName+","+prefixList+","+description+")";
+								
+							}
+			
+							
+							//Replace double quote with single quote
+							insertQuery = insertQuery.replace('"', '\'');
+							
+							//Execute the queries to Insert data
+				            st.executeUpdate(insertQuery);
+							
+							ai++;
+						}
+						
+					}
+						
+					i++;	
+				}
+				
+				/*
+				 * Remove duplicate values from 'lookup' dictionary tables
+				 */
+				//ProtocolList Table
+				String protoDelete = "DELETE FROM protocollist USING protocollist, protocollist p1 "
+						+ "WHERE protocollist.id > p1.id AND protocollist.protocolname = p1.protocolname;";
+				st.addBatch(protoDelete);
+				
+				//PortList Table
+				String portListDelete = "DELETE FROM portlist USING portlist, portlist p1 "
+						+ "WHERE portlist.id > p1.id AND portlist.portname = p1.portname; ";
+				st.addBatch(portListDelete);
+				
+				//PrefixList Table
+				String prefixListDelete = "DELETE FROM prefixlist USING prefixlist, prefixlist p1 "
+						+ "WHERE prefixlist.id > p1.id AND prefixlist.pl_name = p1.pl_name AND "
+						+ "prefixlist.pl_value = p1.pl_value AND prefixlist.description = p1.description; ";
+				st.addBatch(prefixListDelete);
+				
+				//GroupServiceList
+				String groupServiceDelete = "DELETE FROM groupservicelist USING groupservicelist, groupservicelist g1 "
+						+ "WHERE groupservicelist.id > g1.id AND groupservicelist.name = g1.name AND "
+						+ "groupservicelist.serviceList = g1.serviceList; ";
+				st.addBatch(groupServiceDelete);
+				
+				st.executeBatch();
+				
+			} catch (ClassNotFoundException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "FirewallConfigPolicy", "Exception building Firewall queries");
+				System.out.println(e.getMessage());
+				return false;
+	
+			} catch (SQLException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "FirewallConfigPolicy", "Exception executing Firewall queries");
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				try{
+					if (con!=null) con.close();
+					if (rs!=null) rs.close();
+					if (st!=null) st.close();
+				} catch (Exception ex){}
+			}
+			return true;
+	
+		} else {
+			return false;
+		}
+	
+}
+	
+	private JsonObject stringToJson(String jsonString) {
+		
+		JsonObject json = null;
+		if (jsonString != null) {
+			
+			//Read jsonBody to JsonObject
+			StringReader in = null;
+			
+			in = new StringReader(jsonString);
+			
+			JsonReader jsonReader = Json.createReader(in);
+			json = jsonReader.readObject();
+		}
+		
+		return json;
+	}
+		
+		
+	private JsonNode createPatch(String json, String oldJson) {
+		JsonNode oldJason = null;
+		JsonNode updatedJason = null;
+
+		try {
+		oldJason = JsonLoader.fromString(oldJson);
+		updatedJason = JsonLoader.fromString(json);
+		} catch (IOException e) {
+		e.printStackTrace();
+		}
+
+		JsonPatch jsonPatch = JsonDiff.asJsonPatch(oldJason, updatedJason);
+		JsonNode patchNode = JsonDiff.asJson(oldJason, updatedJason);
+		System.out.println("Sending Patch:" + jsonPatch);
+		return patchNode;
+
+		}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}
+
+}
+	
+	
+	
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/MicroServiceConfigPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/MicroServiceConfigPolicy.java
new file mode 100644
index 0000000..c65b0be
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/MicroServiceConfigPolicy.java
@@ -0,0 +1,561 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.json.stream.JsonGenerationException;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.std.IdentifierImpl;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class MicroServiceConfigPolicy extends Policy {
+	
+	/**
+	 * Config Fields
+	 */
+	private static final Logger logger = FlexLogger.getLogger(ConfigPolicy.class);
+
+	public MicroServiceConfigPolicy() {
+		super();
+	}
+	
+	public MicroServiceConfigPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+
+	//save configuration of the policy based on the policyname
+	private void saveConfigurations(String policyName, String prevPolicyName, String jsonBody) {
+		String domain = getParentPathSubScopeDir();
+		String path = domain.replace('\\', '.');
+		if(path.contains("/")){
+			path = domain.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		try {
+			String body = null;
+			try {
+				body = jsonBody;
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+
+			System.out.println(body);
+			if(policyName.endsWith(".xml")){
+				policyName	 = policyName.substring(0, policyName.lastIndexOf(".xml"));	
+			}
+			PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator+path + "."+ policyName +".json");
+			out.println(body);
+			out.close();
+
+		} catch (JsonGenerationException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+	
+	//getting the policy name and setting to configuration on adding .json
+	private String getConfigFile(String filename) {
+		filename = FilenameUtils.removeExtension(filename);
+		if (filename.endsWith(".xml")) {
+			filename = filename.substring(0, filename.length() - 4);
+		}
+		filename = filename +".json";
+		return filename;
+	}
+	
+	@Override
+	public Map<String, String> savePolicies() throws Exception {
+		
+		Map<String, String> successMap = new HashMap<String,String>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+		
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getParentPath().toString(), policyName);
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject() );		
+		if (successMap.containsKey("success")) {
+			Path finalPolicyPath = getFinalPolicyPath();
+			policyAdapter.setFinalPolicyPath(finalPolicyPath.toString());
+		}
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws Exception{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+
+		if (policyAdapter.isEditPolicy()) {
+			version = policyAdapter.getHighestVersion() + 1;
+		} else {
+			version = 1;
+		}
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		
+		if (policyAdapter.getData() != null) {
+			
+			// Save off everything
+			// making ready all the required elements to generate the action policy xml.
+			// Get the uniqueness for policy name.
+			String prevPolicyName = null;
+			if(policyAdapter.isEditPolicy()){
+				prevPolicyName = "Config_MS_" + policyAdapter.getPolicyName() + "." + policyAdapter.getHighestVersion() + ".xml";
+			}
+			
+			Path newFile = this.getNextLoopFilename(Paths.get(policyAdapter.getParentPath()), policyAdapter.getPolicyType(), 
+					policyAdapter.getConfigPolicyType(), policyAdapter.getPolicyName(), version);
+			
+			if (newFile == null) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy already Exists, cannot create the policy.");
+				PolicyLogger.error("Policy already Exists, cannot create the policy.");
+				setPolicyExists(true);
+				return false;
+			}
+			
+			policyName = newFile.getFileName().toString();
+			
+			// Save the Configurations file with the policy name with extention based on selection.
+			String jsonBody = policyAdapter.getJsonBody();
+			saveConfigurations(policyName, prevPolicyName, jsonBody);
+			
+			// Make sure the filename ends with an extension
+			if (policyName.endsWith(".xml") == false) {
+				policyName = policyName + ".xml";
+			}
+			
+	
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+			
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			
+			AllOfType allOfOne = new AllOfType();
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			logger.info("print the main domain value "+policyDir);
+			String path = policyDir.replace('\\', '.');
+			if(path.contains("/")){
+				path = policyDir.replace('/', '.');
+				logger.info("print the path:" +path);
+			}
+			String fileName = FilenameUtils.removeExtension(policyName);
+			fileName = path + "." + fileName + ".xml";
+			String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+			}
+			
+			// Match for policyName
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			
+			AllOfType allOf = new AllOfType();
+		
+			// Adding the matches to AllOfType element Match for Ecomp
+			allOf.getMatch().add(createMatch("ECOMPName", policyAdapter.getEcompName()));
+			// Match for ConfigName
+			allOf.getMatch().add(createMatch("ConfigName", policyAdapter.getConfigName()));
+			// Match for Service
+			allOf.getMatch().add(createDynamicMatch("service", policyAdapter.getServiceType()));
+			// Match for uuid
+			allOf.getMatch().add(createDynamicMatch("uuid", policyAdapter.getUuid()));
+			// Match for location
+			allOf.getMatch().add(createDynamicMatch("location", policyAdapter.getLocation()));
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			((TargetType) target).getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "MicroServiceConfigPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+			configAttributeValue.getContent().add("Config");
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getStackTrace());
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "MicroServiceConfigPolicy", "Exception creating Config URI");
+			}
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+	
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("MSID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+		// For Config file Url if configurations are provided.
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+
+		AttributeValueType AttributeValue = new AttributeValueType();
+		AttributeValue.setDataType(URI_DATATYPE);
+		String policyDir1 = policyAdapter.getParentPath().toString();
+		int startIndex1 = policyDir1.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir1 = policyDir1.substring(startIndex1, policyDir1.length());
+		logger.info("print the main domain value"+policyDir1);
+		String path = policyDir1.replace('\\', '.');
+		if(path.contains("/")){
+			path = policyDir1.replace('/', '.');
+			logger.info("print the path:" +path);
+		}
+		String content = CONFIG_URL +"/Config/" + path + "." + getConfigFile(policyName);
+		System.out.println("URL value :" + content);
+		AttributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory().createAttributeValue(AttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment2);
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		String policyDir = policyAdapter.getParentPath().toString();
+		int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+		policyDir = policyDir.substring(startIndex, policyDir.length());
+		StringTokenizer tokenizer = null;
+		StringBuffer buffer = new StringBuffer();
+		if (policyDir.contains("\\")) {
+			tokenizer = new StringTokenizer(policyDir, "\\");
+		} else {
+			tokenizer = new StringTokenizer(policyDir, "/");
+		}
+		if (tokenizer != null) {
+			while (tokenizer.hasMoreElements()) {
+				String value = tokenizer.nextToken();
+				buffer.append(value);
+				buffer.append(".");
+			}
+		}
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = buffer.toString() + fileName + ".xml";
+		String name = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
+		}
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + this.ECOMPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getEcompName());
+		assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+
+		advice.getAttributeAssignmentExpression().add(assignment5);
+
+		AttributeAssignmentExpressionType assignment6 = new AttributeAssignmentExpressionType();
+		assignment6.setAttributeId("matching:" + this.CONFIGID);
+		assignment6.setCategory(CATEGORY_RESOURCE);
+		assignment6.setIssuer("");
+
+		AttributeValueType configNameAttributeValue6 = new AttributeValueType();
+		configNameAttributeValue6.setDataType(STRING_DATATYPE);
+		configNameAttributeValue6.getContent().add(policyAdapter.getConfigName());
+		assignment6.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue6));
+
+		advice.getAttributeAssignmentExpression().add(assignment6);
+		AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+		assignment7.setAttributeId("matching:service");
+		assignment7.setCategory(CATEGORY_RESOURCE);
+		assignment7.setIssuer("");
+
+		AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+		configNameAttributeValue7.setDataType(STRING_DATATYPE);
+		configNameAttributeValue7.getContent().add(policyAdapter.getServiceType());
+		assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+
+		advice.getAttributeAssignmentExpression().add(assignment7);
+		
+		AttributeAssignmentExpressionType assignment8 = new AttributeAssignmentExpressionType();
+		assignment8.setAttributeId("matching:uuid");
+		assignment8.setCategory(CATEGORY_RESOURCE);
+		assignment8.setIssuer("");
+
+		AttributeValueType configNameAttributeValue8 = new AttributeValueType();
+		configNameAttributeValue8.setDataType(STRING_DATATYPE);
+		configNameAttributeValue8.getContent().add(policyAdapter.getUuid());
+		assignment8.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue8));
+
+		advice.getAttributeAssignmentExpression().add(assignment8);
+        
+		AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+		assignment9.setAttributeId("matching:Location");
+		assignment9.setCategory(CATEGORY_RESOURCE);
+		assignment9.setIssuer("");
+
+		AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+		configNameAttributeValue9.setDataType(STRING_DATATYPE);
+		configNameAttributeValue9.getContent().add(policyAdapter.getLocation());
+		assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+
+		advice.getAttributeAssignmentExpression().add(assignment9);
+		
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("Priority");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getPriority());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+		
+		//Risk Attributes
+		AttributeAssignmentExpressionType assignment11 = new AttributeAssignmentExpressionType();
+		assignment11.setAttributeId("RiskType");
+		assignment11.setCategory(CATEGORY_RESOURCE);
+		assignment11.setIssuer("");
+
+		AttributeValueType configNameAttributeValue11 = new AttributeValueType();
+		configNameAttributeValue11.setDataType(STRING_DATATYPE);
+		configNameAttributeValue11.getContent().add(policyAdapter.getRiskType());
+		assignment11.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue11));
+
+		advice.getAttributeAssignmentExpression().add(assignment11);
+		
+		AttributeAssignmentExpressionType assignment12 = new AttributeAssignmentExpressionType();
+		assignment12.setAttributeId("RiskLevel");
+		assignment12.setCategory(CATEGORY_RESOURCE);
+		assignment12.setIssuer("");
+
+		AttributeValueType configNameAttributeValue12 = new AttributeValueType();
+		configNameAttributeValue12.setDataType(STRING_DATATYPE);
+		configNameAttributeValue12.getContent().add(policyAdapter.getRiskLevel());
+		assignment12.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue12));
+
+		advice.getAttributeAssignmentExpression().add(assignment12);	
+
+		AttributeAssignmentExpressionType assignment13 = new AttributeAssignmentExpressionType();
+		assignment13.setAttributeId("guard");
+		assignment13.setCategory(CATEGORY_RESOURCE);
+		assignment13.setIssuer("");
+
+		AttributeValueType configNameAttributeValue13 = new AttributeValueType();
+		configNameAttributeValue13.setDataType(STRING_DATATYPE);
+		configNameAttributeValue13.getContent().add(policyAdapter.getRiskLevel());
+		assignment13.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue13));
+
+		advice.getAttributeAssignmentExpression().add(assignment13);
+		
+		AttributeAssignmentExpressionType assignment14 = new AttributeAssignmentExpressionType();
+		assignment14.setAttributeId("TTLDate");
+		assignment14.setCategory(CATEGORY_RESOURCE);
+		assignment14.setIssuer("");
+
+		AttributeValueType configNameAttributeValue14 = new AttributeValueType();
+		configNameAttributeValue14.setDataType(STRING_DATATYPE);
+		configNameAttributeValue14.getContent().add(policyAdapter.getTtlDate());
+		assignment14.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue14));
+
+		advice.getAttributeAssignmentExpression().add(assignment14);
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}	
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/Policy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/Policy.java
new file mode 100644
index 0000000..09c90de
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/Policy.java
@@ -0,0 +1,455 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonReader;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.rest.XACMLRestProperties;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.std.IdentifierImpl;
+import org.openecomp.policy.xacml.util.XACMLPolicyWriter;
+import com.att.research.xacml.util.XACMLProperties;
+import com.att.research.xacmlatt.pdp.policy.PolicyDef;
+import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public abstract class Policy {
+
+	/**
+	 * Common Fields
+	 */
+	public static final String GET_INT_TYPE = "Integer";
+	public static final String GET_STRING_TYPE = "String";
+
+	public static final String ECOMPID = "ECOMPName";
+	public static final String CONFIGID = "ConfigName";
+	public static final String CLOSEDLOOPID = "ServiceType";
+	
+	public static final String CONFIG_POLICY = "Config";
+	public static final String ACTION_POLICY = "Action";
+	public static final String DECISION_POLICY = "Decision";
+
+	protected String policyName = null;
+	private static final Logger logger = FlexLogger.getLogger(Policy.class);
+	
+	boolean isValidForm = true;
+	
+	private Path finalPolicyPath = null;
+	
+	private boolean preparedToSave = false;
+	
+	private boolean policyExists = false;
+	
+	public Path getFinalPolicyPath() {
+		return finalPolicyPath;
+	}
+
+	public void setFinalPolicyPath(Path finalPolicyPath) {
+		this.finalPolicyPath = finalPolicyPath;
+	}
+
+		// Constants Used in XML Creation
+		public static final String CATEGORY_RECIPIENT_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
+		public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
+		public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
+		public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
+		public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
+		public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
+		public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
+		public static final String FUNTION_INTEGER_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
+		public static final String FUNCTION_STRING_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
+		public static final String FUNCTION_BOOLEAN_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only";
+		public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
+		public static final String FUNCTION_STRING_REGEX_MATCH = "org.openecomp.function.regex-match";
+		public static final String FUNCTION_STRING_EQUAL_IGNORE = "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
+		public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
+		public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
+		public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
+		public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
+		public static final String RULE_VARIABLE = "var:";
+		public static final String EMPTY_STRING = "";
+		private static final String String = null;
+		
+		public static String CONFIG_HOME = null;
+		public static String ACTION_HOME = null;
+		public static String CONFIG_URL = null;
+		
+		protected Map<String, String> performer = new HashMap<String, String>();
+		
+		private static String actionHome = null;
+		private static String configHome = null;
+
+		public PolicyRestAdapter policyAdapter = null;
+		String ruleID = "";
+		
+		public Policy() {
+			CONFIG_HOME = getConfigHome();
+			ACTION_HOME = getActionHome();
+			CONFIG_URL = "$URL";
+			performer.put("PDP", "PDPAction");
+			performer.put("PEP", "PEPAction");
+		}
+
+		//Each policy type seems to either use policyData or data field policy adapter when
+		//getting the xml to save the policy. Instead of keep this hardcoded in the save method,
+		//this method makes it usable outside.
+		/**
+		 * Return the data field of the PolicyAdapter that will be used when saving this policy
+		 * with the savePolicies method.
+		 * @return Either the PolicyAdapter.getData() or PolicyAdapter.getPolicyData()
+		 */
+		public abstract Object getCorrectPolicyDataObject();
+		public abstract Map<String, String>  savePolicies() throws Exception;
+		
+		//This is the method for preparing the policy for saving.  We have broken it out
+		//separately because the fully configured policy is used for multiple things
+		public abstract boolean prepareToSave() throws Exception;
+
+		
+		// create match for ecomp and config name
+		protected MatchType createMatch(String key, String value) {
+			MatchType match = new MatchType();
+
+			AttributeValueType attributeValue = new AttributeValueType();
+			attributeValue.setDataType(STRING_DATATYPE);
+			attributeValue.getContent().add(value);
+			match.setAttributeValue(attributeValue);
+			AttributeDesignatorType attributeDesignator = new AttributeDesignatorType();
+			URI uri = null;
+			try {
+				uri = new URI(key);
+			} catch (URISyntaxException e) {
+				e.printStackTrace();
+			}
+			attributeDesignator.setCategory(CATEGORY_ACCESS_SUBJECT);
+			attributeDesignator.setDataType(STRING_DATATYPE);
+			attributeDesignator.setAttributeId(new IdentifierImpl(uri).stringValue());
+			match.setAttributeDesignator(attributeDesignator);
+			match.setMatchId(FUNCTION_STRING_REGEX_MATCH);
+			return match;
+		}
+		
+		// Creating the match for dynamically added components.
+		protected MatchType createDynamicMatch(String key, String value) {
+			MatchType dynamicMatch = new MatchType();
+			AttributeValueType dynamicAttributeValue = new AttributeValueType();
+			//Attribute attribute = findAttributeByAttributeId(key);
+			String dataType = null;
+	//		if (value.matches("[0-9]+")) {
+	//			dataType = INTEGER_DATATYPE;
+	//		} else {
+	//			dataType = STRING_DATATYPE;
+	//		}
+			dataType = STRING_DATATYPE;
+			dynamicAttributeValue.setDataType(dataType);
+			dynamicAttributeValue.getContent().add(value);
+			dynamicMatch.setAttributeValue(dynamicAttributeValue);
+
+			AttributeDesignatorType dynamicAttributeDesignator = new AttributeDesignatorType();
+
+			URI dynamicURI = null;
+			try {
+				dynamicURI = new URI(key);
+			} catch (URISyntaxException e) {
+				e.printStackTrace();// log msg
+			}
+			dynamicAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			dynamicAttributeDesignator.setDataType(dataType);
+			dynamicAttributeDesignator.setAttributeId(new IdentifierImpl(dynamicURI).stringValue());
+			dynamicMatch.setAttributeDesignator(dynamicAttributeDesignator);
+			dynamicMatch.setMatchId(FUNCTION_STRING_REGEX_MATCH);
+
+			return dynamicMatch;
+		}
+
+		//validation for numeric
+		protected boolean isNumeric(String str)
+		{
+			for (char c : str.toCharArray())
+			{
+				if (!Character.isDigit(c)) return false;
+			}
+			return true;
+		}
+		
+		// Validation for json.
+		protected static boolean isJSONValid(String data) {
+			try {
+				new JSONObject(data);
+				InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+				JsonReader jsonReader = Json.createReader(stream);
+				System.out.println("Json Value is: " + jsonReader.read().toString() );
+			} catch (Exception e) {
+				return false;
+			}
+			return true;
+		}
+		
+		//  the Policy Name as Unique One throws error
+		protected Path getNextFilename(Path parent, String policyType, String polcyFileName, Integer version) {
+			policyType = FilenameUtils.removeExtension(policyType);
+			polcyFileName = FilenameUtils.removeExtension(polcyFileName);
+			Path newFile = null;
+			String policyDir = EMPTY_STRING;
+			String absolutePath = parent.toString();
+			if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
+				policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
+				if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
+					policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
+				}
+			}
+
+			String fileName = "default";
+			if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
+				fileName = policyType + "_" + String.format(polcyFileName) + "." + version + ".xml";
+			} 
+			if (fileName != null) {
+				newFile = Paths.get(parent.toString(), fileName);
+			}
+			if (Files.notExists(newFile)) {
+				return newFile;
+			}
+			return null;
+		}
+		
+		protected Path getNextLoopFilename(Path parentPath, String policyType,
+				String policyConfigType, String policyFileName, Integer version) {
+			policyType = FilenameUtils.removeExtension(policyType);
+			policyConfigType = FilenameUtils.removeExtension(policyConfigType);
+			policyFileName = FilenameUtils.removeExtension(policyFileName);
+			Path newFile = null;
+			String policyDir = EMPTY_STRING;
+			String absolutePath = parentPath.toString();
+			if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
+				policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
+				if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
+					policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
+				}
+			}
+
+			String fileName = "default";
+			if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
+				if(policyConfigType.equals("ClosedLoop_PM")){
+					fileName = policyType + "_" + "PM" + "_" +java.lang.String.format(policyFileName) + "." +version +".xml";
+				}else if(policyConfigType.equals("ClosedLoop_Fault")){
+					fileName = policyType + "_" + "Fault" + "_" +java.lang.String.format(policyFileName) +  "." + version + ".xml";
+				}else if(policyConfigType.equals("ClosedLoop_Fault")){
+					fileName = policyType + "_" + "Fault" + "_" +java.lang.String.format(policyFileName) +  "." + version + ".xml";
+				}else if(policyConfigType.equals("DCAE Micro Service")){
+					fileName = policyType + "_" + "MS" + "_" + java.lang.String.format(policyFileName) + "." + version + ".xml";
+				}
+			} 
+			if (fileName != null) {
+				newFile = Paths.get(parentPath.toString(), fileName);
+			}
+			if (Files.notExists(newFile)) {
+				return newFile;
+			}
+			return null;
+		}
+		
+		
+		//create policy once all the validations are completed
+		protected Map<String, String> createPolicy(final Path policyPath, final Object policyData) {
+			Map<String, String> success = new HashMap<String, String>(); 
+			//
+			// Is the root a PolicySet or Policy?
+			//
+			
+			if (policyData instanceof PolicyType) {
+				//
+				// Write it out
+				//
+				//Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
+				//and this transaction is intercepted up stream.
+				InputStream inputStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType) policyData);
+				try {
+					PolicyDef policyDef = DOMPolicyDef.load(inputStream);
+					if (policyDef != null) {
+						//This is does not need to be XACMLPolicyWriterWithPapNotification since it is already in the PAP
+						//and the transaction was intercepted up stream
+						finalPolicyPath = XACMLPolicyWriter.writePolicyFile(policyPath, (PolicyType) policyData);
+						this.setFinalPolicyPath(finalPolicyPath);
+					} else{
+						success.put("validation", "PolicyDef Validation Failed");
+					}
+				} catch (Exception e) {
+					success.put("error", "Validation Failed");
+				}
+				
+			} else {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Unknown data type sent back.");
+				PolicyLogger.error("Unknown data type sent back.");
+				return success;
+			}
+			//
+			// Did it get written?
+			//
+			if (finalPolicyPath == null || !Files.exists(finalPolicyPath)) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Failed to write policy file.");
+				PolicyLogger.error("Failed to write policy file.");
+				return success;
+			}
+			try {
+				success.put("success", "success");
+			} finally {
+				// vaadin framework will handle exception.
+			}
+			return success;
+		}
+		
+		public static String getConfigHome(){
+			try {
+				loadWebapps();
+			} catch (Exception e) {
+				return null;
+			}
+			return configHome;
+		}
+		
+		public static String getActionHome(){
+			try {
+				loadWebapps();
+			} catch (Exception e) {
+				return null;
+			}
+			return actionHome;
+		}
+		
+		private static void loadWebapps() throws Exception{
+			if(actionHome == null || configHome == null){
+				Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS));
+				//Sanity Check
+				if (webappsPath == null) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
+					PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
+					throw new Exception("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
+				}
+				Path webappsPathConfig;
+				Path webappsPathAction;
+				if(webappsPath.toString().contains("\\"))
+				{
+					webappsPathConfig = Paths.get(webappsPath.toString()+"\\Config");
+					webappsPathAction = Paths.get(webappsPath.toString()+"\\Action");
+				}
+				else
+				{
+					webappsPathConfig = Paths.get(webappsPath.toString()+"/Config");
+					webappsPathAction = Paths.get(webappsPath.toString()+"/Action");
+				}
+				if (Files.notExists(webappsPathConfig)) 
+				{
+					try {
+						Files.createDirectories(webappsPathConfig);
+					} catch (IOException e) {
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
+								//+ webappsPathConfig.toAbsolutePath().toString(), e);
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy", "Failed to create config directory");
+					}
+				}
+				if (Files.notExists(webappsPathAction)) 
+				{
+					try {
+						Files.createDirectories(webappsPathAction);
+					} catch (IOException e) {
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create config directory: "
+								//+ webappsPathAction.toAbsolutePath().toString(), e);
+						PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy", "Failed to create config directory");
+					}
+				}
+				actionHome = webappsPathAction.toString();
+				configHome = webappsPathConfig.toString();
+			}
+		}
+		
+		protected String getParentPathSubScopeDir() {
+
+			final Path gitPath = Paths.get(policyAdapter.getUserGitPath().toString());
+			String policyDir = policyAdapter.getParentPath().toString();
+			int startIndex = policyDir.indexOf(gitPath.toString()) + gitPath.toString().length() + 1;
+			policyDir = policyDir.substring(startIndex, policyDir.length());
+			
+			return policyDir;
+		}
+
+
+		public boolean validateConfigForm() {
+			// TODO Auto-generated method stub
+			return true;
+		}
+
+		/**
+		 * @return the preparedToSave
+		 */
+		public boolean isPreparedToSave() {
+			return preparedToSave;
+		}
+
+		/**
+		 * @param preparedToSave the preparedToSave to set
+		 */
+		protected void setPreparedToSave(boolean preparedToSave) {
+			this.preparedToSave = preparedToSave;
+		}
+
+		public boolean isPolicyExists() {
+			return policyExists;
+		}
+
+		public void setPolicyExists(boolean policyExists) {
+			this.policyExists = policyExists;
+		}
+		
+		
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java
new file mode 100644
index 0000000..bdd7534
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java
@@ -0,0 +1,3936 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.Key;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.LockModeType;
+import javax.persistence.PersistenceException;
+import javax.persistence.Query;
+import javax.persistence.RollbackException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet;
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.rest.XACMLRestProperties;
+import org.openecomp.policy.rest.jpa.ActionBodyEntity;
+import org.openecomp.policy.rest.jpa.ConfigurationDataEntity;
+import org.openecomp.policy.rest.jpa.DatabaseLockEntity;
+import org.openecomp.policy.rest.jpa.GroupEntity;
+import org.openecomp.policy.rest.jpa.PdpEntity;
+import org.openecomp.policy.rest.jpa.PolicyDBDaoEntity;
+import org.openecomp.policy.rest.jpa.PolicyEntity;
+import org.openecomp.policy.rest.jpa.PolicyVersion;
+import org.openecomp.policy.rest.util.Webapps;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+import org.xml.sax.InputSource;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import org.openecomp.policy.xacml.api.pap.EcompPDP;
+import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
+import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine;
+
+import com.att.research.xacml.api.pap.PAPEngine;
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.api.pap.PDP;
+//import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
+import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
+import org.openecomp.policy.xacml.util.XACMLPolicyScanner;
+import org.openecomp.policy.xacml.util.XACMLPolicyWriter;
+import com.att.research.xacml.util.XACMLProperties;
+
+import org.w3c.dom.Document;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class PolicyDBDao {
+	private static final Logger logger	= FlexLogger.getLogger(PolicyDBDao.class);		
+	private List<?> otherServers;
+	private EntityManagerFactory emf;
+	private static PolicyDBDao currentInstance = null;
+	private PAPPolicyEngine papEngine;
+	
+	public static final String JSON_CONFIG = "JSON";
+	public static final String XML_CONFIG = "XML";
+	public static final String PROPERTIES_CONFIG = "PROPERTIES";
+	public static final String OTHER_CONFIG = "OTHER";
+	public static final String AUDIT_USER = "audit";
+	
+	/**
+	 * Get an instance of a PolicyDBDao. It creates one if it does not exist.
+	 * Only one instance is allowed to be created per server.
+	 * @param emf The EntityFactoryManager to be used for database connections
+	 * @return The new instance of PolicyDBDao or throw exception if the given emf is null.
+	 * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this.
+	 */
+	public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) throws Exception{
+		logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called");
+		if(currentInstance == null){
+			if(emf != null){
+				currentInstance = new PolicyDBDao(emf);
+				return currentInstance;
+			}
+			throw new IllegalStateException("The EntityManagerFactory is Null");
+		}
+		return currentInstance;
+	}
+	
+	/**
+	 * Gets the current instance of PolicyDBDao. 
+	 * @return The instance of PolicyDBDao or throws exception if the given instance is null.
+	 * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this.
+	 */
+	public static PolicyDBDao getPolicyDBDaoInstance() throws Exception{
+		logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called");
+		if(currentInstance != null){
+			return currentInstance;
+		}
+		throw new IllegalStateException("The PolicyDBDao.currentInstance is Null.  Use getPolicyDBDao(EntityManagerFactory emf)");
+	}
+	public void setPapEngine(PAPPolicyEngine papEngine2){
+		this.papEngine = (PAPPolicyEngine) papEngine2;
+	}
+	private PolicyDBDao(EntityManagerFactory emf){
+		logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao("+emf+") called");
+		this.emf = emf;
+		
+		//not needed in this release
+		if(!register()){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
+			PolicyLogger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
+		}
+		
+		otherServers = getRemotePolicyDBDaoList();
+		if(logger.isDebugEnabled()){
+			logger.debug("Number of remote PolicyDBDao instances: "+otherServers.size());
+		}
+		if(otherServers.size() < 1){
+			logger.warn("List of PolicyDBDao servers is empty or could not be retrieved");
+		}
+		//otherServers = new LinkedList();		
+		//otherServers.add((Object)"http://localhost:8071/pap/");		
+	}
+	
+	//not static because we are going to be using the instance's emf
+	//waitTime in ms to wait for lock, or -1 to wait forever (no)
+	private void startTransactionSynced(EntityManager entityMgr,int waitTime){
+		logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as "
+				+ "\n   startTransactionSynced("+entityMgr+","+waitTime+") called\n\n");
+		DatabaseLockEntity lock = null;		
+		
+		entityMgr.setProperty("javax.persistence.query.timeout", waitTime);
+		entityMgr.getTransaction().begin();
+		
+			if(logger.isDebugEnabled()){
+				Map<String,Object> properties = entityMgr.getProperties();
+				logger.debug("\n\nstartTransactionSynced():"
+						+ "\n   entityManager.getProperties() = " + properties 
+						+ "\n\n");
+			}
+			try{
+				if(logger.isDebugEnabled()){
+					logger.debug("\n\nstartTransactionSynced():"
+							+ "\n   ATTEMPT to get the DB lock"
+							+ "\n\n");
+				}
+				lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE);
+				if(logger.isDebugEnabled()){
+					logger.debug("\n\nstartTransactionSynced():"
+							+ "\n   GOT the DB lock"
+							+ "\n\n");
+				}
+			} catch(Exception e){
+				System.out.println("Could not get lock entity");
+				e.printStackTrace();
+			}
+		if(lock == null){
+			throw new IllegalStateException("The lock row does not exist in the table. Please create a primary key with value = 1.");	
+		}
+
+	}
+	/**
+	 * Gets the list of other registered PolicyDBDaos from the database
+	 * @return List (type PolicyDBDaoEntity) of other PolicyDBDaos
+	 */
+	private List<?> getRemotePolicyDBDaoList(){
+		logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called");
+		List<?> policyDBDaoEntityList = new LinkedList<Object>();
+		EntityManager em = emf.createEntityManager();
+		startTransactionSynced(em, 1000);
+		try{						
+			Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll");			
+			policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList();
+			
+		} catch(Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Caught Exception on: getPolicyDBDaoEntityQuery.getResultList()",e);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception querying for other registered PolicyDBDaos");
+			logger.warn("List of remote PolicyDBDaos will be empty");
+		}
+		try{
+		em.getTransaction().commit();
+		} catch(Exception e){
+			try{
+				em.getTransaction().rollback();
+			} catch(Exception e2){
+				
+			}
+		}
+		em.close();
+		return policyDBDaoEntityList;
+	}
+	
+	public PolicyDBDaoTransaction getNewTransaction(){
+		logger.debug("getNewTransaction() as getNewTransaction() called");
+		return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance());
+	}
+	
+	/*
+	 * Because the normal transactions are not used in audits, we can use the same transaction
+	 * mechanism to get a transaction and obtain the emlock and the DB lock.  We just need to
+	 * provide different transaction timeout values in ms because the audit will run longer
+	 * than normal transactions.
+	 */
+	public PolicyDBDaoTransaction getNewAuditTransaction(){
+		logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called");
+		//Use the standard transaction wait time in ms
+		int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
+		//Use the (extended) audit timeout time in ms
+		int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); 
+		return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs));
+	}
+	
+	
+	/**
+	 * Checks if two strings are equal. Null strings ARE allowed.
+	 * @param one A String or null to compare
+	 * @param two A String or null to compare
+	 */
+	private static boolean stringEquals(String one, String two){
+		logger.debug("stringEquals(String one, String two) as stringEquals("+one+", "+two+") called");
+		if(one == null && two == null){
+			return true;
+		}
+		if(one == null || two == null){
+			return false;
+		}
+		return one.equals(two);
+	}
+	
+	/**
+	 * Computes the scope in dotted format based on an absolute path and a path that divides the scope.
+	 * @param fullPath An absolute path including scope folders and other folders(does not have to be absolute, must just contain scope and other folders before)
+	 * @param pathToExclude The path that acts as a division between the scope and the other folders
+	 * @return The scope in dotted format (org.openecomp)
+	 */
+	private static String computeScope(String fullPath, String pathToExclude){
+		logger.debug("computeScope(String fullPath, String pathToExclude) as computeScope("+fullPath+", "+pathToExclude+") called");
+		int excludeIndex = fullPath.indexOf(pathToExclude);
+		String scopePath = fullPath.substring(excludeIndex+pathToExclude.length());
+		String scope = scopePath.replace('\\', '.');
+		scope = scope.replace('/', '.');
+		if(scope.charAt(0) == '.'){
+			scope = scope.substring(1);
+		}
+		if(scope.charAt(scope.length()-1) == '.'){
+			scope = scope.substring(0, scope.length()-1);
+		}
+		return scope;
+	}
+
+	/**
+	 * Returns the url of this local pap server, removing the username and password, if they are present
+	 * @return The url of this local pap server
+	 */
+	private String[] getPapUrlUserPass(){
+		logger.debug("getPapUrl() as getPapUrl() called");
+		String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
+		if(url == null){
+			return null;
+		}
+		return splitPapUrlUserPass(url);
+
+
+	}
+	private String[] splitPapUrlUserPass(String url){
+		String[] urlUserPass = new String[3];
+		String[] commaSplit = url.split(",");
+		urlUserPass[0] = commaSplit[0];
+		if(commaSplit.length > 2){
+			urlUserPass[1] = commaSplit[1];
+			urlUserPass[2] = commaSplit[2];
+		}
+		if(urlUserPass[1] == null || urlUserPass[1].equals("")){
+			String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
+			if(usernamePropertyValue != null){
+				urlUserPass[1] = usernamePropertyValue;
+			}
+		}
+		if(urlUserPass[2] == null || urlUserPass[2].equals("")){
+			String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
+			if(passwordPropertyValue != null){
+				urlUserPass[2] = passwordPropertyValue;
+			}
+		}
+		//if there is no comma, for some reason there is no username and password, so don't try to cut them off
+		return urlUserPass;
+	}
+	
+	private static String encryptPassword(String password) throws Exception{
+		Cipher cipher = Cipher.getInstance("AES");		
+		cipher.init(Cipher.ENCRYPT_MODE, aesKey());
+		byte[] encryption = cipher.doFinal(password.getBytes("UTF-8"));
+		System.out.println(encryption);
+		return new String(Base64.getMimeEncoder().encode(encryption),"UTF-8");
+	}
+	
+	private static String decryptPassword(String encryptedPassword) throws Exception{
+		Cipher cipher = Cipher.getInstance("AES");
+		cipher.init(Cipher.DECRYPT_MODE, aesKey());
+		byte[] password = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword.getBytes("UTF-8")));
+		return new String(password,"UTF-8");
+	}
+	private static Key aesKey(){
+		byte[] aesValue = (new String("njrmbklcxtoplawf")).getBytes();
+		return new SecretKeySpec(aesValue,"AES");
+	}
+	/**
+	 * Register the PolicyDBDao instance in the PolicyDBDaoEntity table
+	 * @return Boolean, were we able to register?
+	 */
+	private boolean register(){
+		logger.debug("register() as register() called");
+		String[] url = getPapUrlUserPass();
+		EntityManager em = emf.createEntityManager();
+		try{
+			startTransactionSynced(em, 1000);
+		} catch(IllegalStateException e){
+			logger.debug ("\nPolicyDBDao.register() caught an IllegalStateException: \n" +e + "\n");
+			DatabaseLockEntity lock;
+			lock = em.find(DatabaseLockEntity.class, 1);
+			if(lock==null){				
+				lock = new DatabaseLockEntity();
+				em.persist(lock);
+				lock.setKey(1);
+				try{
+					em.flush();
+					em.getTransaction().commit();
+					em.close();					
+				} catch(Exception e2){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("COULD NOT CREATE DATABASELOCK ROW.  WILL TRY ONE MORE TIME \n\n Exception: \n" + e2);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "COULD NOT CREATE DATABASELOCK ROW.  WILL TRY ONE MORE TIME");
+					e2.printStackTrace();
+				}
+				em = null;
+				em = emf.createEntityManager();
+				try{
+					startTransactionSynced(em, 1000);
+				} catch(Exception e3){
+					//still not working
+					String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING";
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(msg);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, "PolicyDBDao", msg);
+					throw new IllegalStateException("msg" + "\n" + e3);
+				}
+			}
+		}
+		logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n");
+		PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]);
+		Query getPolicyDBDaoEntityQuery = em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url");
+		getPolicyDBDaoEntityQuery.setParameter("url", url[0]);
+		if(foundPolicyDBDaoEntity == null){
+			//em.getTransaction().begin();
+			PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity();
+			em.persist(newPolicyDBDaoEntity);
+			newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]);
+			newPolicyDBDaoEntity.setDescription("PAP server at "+url[0]);
+			newPolicyDBDaoEntity.setUsername(url[1]);
+			try{
+			newPolicyDBDaoEntity.setPassword(encryptPassword(url[2]));
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Could not encrypt PAP password",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
+			}
+			/*
+			try{
+				em.getTransaction().commit();
+			} catch(RollbackException e){
+				logger.error("Caught RollbackException during PolicyDBDao Registration on: em.getTransaction().commit()",e);
+				em.close();
+				return false;
+			} catch(Exception e2){
+				logger.error("Caught Exception during PolicyDBDao Registration on: em.getTransaction().commit()",e2);
+				em.close();
+				return false;
+			}
+			*/
+			try{
+				em.getTransaction().commit();
+				} catch(Exception e){
+					try{
+						em.getTransaction().rollback();
+					} catch(Exception e2){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Could not add new PolicyDBDao to the database",e);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not add new PolicyDBDao to the database");
+					}
+				}
+		} else {
+			//em.getTransaction().begin();
+			//just want to update in order to change modified date
+			String encryptedPassword = null;
+			try{
+			encryptedPassword = encryptPassword(url[2]);
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Could not encrypt PAP password",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
+			}
+			if(url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())){
+			foundPolicyDBDaoEntity.setUsername(url[1]);
+			}
+			if(encryptedPassword != null && !stringEquals(encryptedPassword, foundPolicyDBDaoEntity.getPassword())){
+				foundPolicyDBDaoEntity.setPassword(encryptedPassword);
+			}
+			foundPolicyDBDaoEntity.preUpdate();
+			try{
+				em.getTransaction().commit();
+				} catch(Exception e){
+					try{
+						em.getTransaction().rollback();
+					} catch(Exception e2){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Could not update PolicyDBDao in the database",e);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not update PolicyDBDao in the database");
+					}
+				}
+			/*
+			try{
+				em.getTransaction().commit();
+			} catch(RollbackException e){
+				logger.error("Caught RollbackException during PolicyDBDao Registration on: em.getTransaction().commit()",e);
+				em.close();
+				return false;
+			} catch(Exception e2){
+				logger.error("Caught Exception during PolicyDBDao Registration on: em.getTransaction().commit()",e2);
+				em.getTransaction().rollback();
+				return false;
+			}
+			*/
+		}
+		em.close();
+		logger.debug("\nPolicyDBDao.register(). Success!!\n");
+		return true;
+	}
+	public void notifyOthers(long entityId,String entityType){
+		notifyOthers(entityId,entityType,null);
+	}
+	public void notifyOthers(long entityId, String entityType, String newGroupId){
+		logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers("+entityId+","+entityType+","+newGroupId+") called");		
+		LinkedList<Thread> notifyThreads = new LinkedList<Thread>();
+		
+		//we're going to run notiftions in parellel threads to speed things up
+		for(Object obj : otherServers){
+
+			Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId));
+			
+			newNotifyThread.start();
+
+			notifyThreads.add(newNotifyThread);
+
+		}
+		//we want to wait for all notifications to complete or timeout before we unlock the interface and allow more changes
+		for(Thread t : notifyThreads){
+			try {
+				t.join();
+			} catch (Exception e) {
+				logger.warn("Could not join a notifcation thread");
+			}
+		}
+
+		
+	}
+
+	private class NotifyOtherThread implements Runnable {
+		public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId){
+			this.obj = obj;
+			this.entityId = entityId;
+			this.entityType = entityType;
+			this.newGroupId = newGroupId;
+		}
+		private Object obj;
+		private long entityId;
+		private String entityType;
+		private String newGroupId;
+		@Override
+		public void run(){
+			//naming of 'o' is for backwards compatibility with the rest of the function
+			PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity)obj;
+			String o = dbdEntity.getPolicyDBDaoUrl();
+			String username = dbdEntity.getUsername();
+			String password;
+			try{
+			password = decryptPassword(dbdEntity.getPassword());
+			} catch(Exception e){
+				//if we can't decrypt, might as well try it anyway
+				password = dbdEntity.getPassword();
+			}
+			Base64.Encoder encoder = Base64.getEncoder();			
+			String encoding = encoder.encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
+			HttpURLConnection connection = null;
+			UUID requestID = UUID.randomUUID();
+			//loggingContext.setRequestID(requestID.toString());
+			//loggingContext.transactionStarted();
+			URL url;
+			try {
+				String papUrl = getPapUrlUserPass()[0];
+				if(papUrl == null){
+					papUrl = "undefined";
+				}
+				logger.debug("We are going to try to notify "+o);
+				//is this our own url?
+				String ourUrl = o;
+				try{
+					ourUrl = splitPapUrlUserPass((String)o)[0];
+				}catch(Exception e){
+					ourUrl = o;
+				}
+				if(o == null){
+					o = "undefined";
+				}
+				if(papUrl.equals(ourUrl)){
+					logger.debug(((String)o)+" is our url, skipping notify");
+					return;
+				}
+				if(newGroupId == null){
+				url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType);
+				} else {
+					url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType+"&extradata="+newGroupId);
+				}
+			} catch (MalformedURLException e) {
+				logger.warn("Caught MalformedURLException on: new URL()", e);
+				return;
+			}
+			//
+			// Open up the connection
+			//
+			logger.debug("Connecting with url: "+url);
+			try {
+				connection = (HttpURLConnection)url.openConnection();
+			} catch (Exception e) {
+				logger.warn("Caught exception on: url.openConnection()",e);
+				return;
+			}
+			//
+			// Setup our method and headers
+			//
+	        try {
+				connection.setRequestMethod("PUT");
+			} catch (ProtocolException e) {
+				//why would this error ever occur?
+				logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");",e);			
+				return;
+			}
+	        connection.setRequestProperty("Authorization", "Basic " + encoding);
+			connection.setRequestProperty("Accept", "text/x-java-properties");
+	        connection.setRequestProperty("Content-Type", "text/x-java-properties");	  	        	        
+	        connection.setRequestProperty("requestID", requestID.toString());
+	        int readTimeout;
+	        try{
+	        	readTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT));
+	        	
+	        } catch(Exception e){
+	        	logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default.");
+	        	readTimeout = 10000;
+	        }
+	        connection.setReadTimeout(readTimeout);
+	        connection.setConnectTimeout(readTimeout);
+	        connection.setUseCaches(false);
+	        //
+	        // Adding this in. It seems the HttpUrlConnection class does NOT
+	        // properly forward our headers for POST re-direction. It does so
+	        // for a GET re-direction.
+	        //
+	        // So we need to handle this ourselves.
+	        //
+	        connection.setInstanceFollowRedirects(false);
+			connection.setDoOutput(true);
+			connection.setDoInput(true);
+	        try {
+				connection.connect();
+			} catch (Exception e) {
+				logger.warn("Caught exception on: connection.connect()",e);
+				return;
+			}
+	        try {
+				if (connection.getResponseCode() == 200) {
+					logger.info("Received response 200 from pap server on notify");
+					//notified = true;
+				} else {
+					logger.warn("connection response code not 200, received: "+connection.getResponseCode());
+				}
+			} catch (Exception e) {
+				logger.warn("Caught Exception on: connection.getResponseCode() ", e);
+			}
+			
+			
+			connection.disconnect();
+		}
+	}
+	
+	private static String getElementFromXMLString(String element, String xml) {
+		InputSource source = new InputSource(new StringReader(xml));
+
+		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+		String description = "";
+		try{
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			Document document = db.parse(source);
+
+			XPathFactory xpathFactory = XPathFactory.newInstance();
+			XPath xpath = xpathFactory.newXPath();
+			
+			if (element.endsWith("/")){
+				element = element.substring(0, element.length() -1);
+			}
+
+			description = xpath.evaluate("/Policy" + element + "/text()", document);		
+		}catch(Exception e){
+			
+		}
+
+
+		System.out.println("description_" + description);
+		return description;
+	}
+	private static String evaluateXPath(String expression, String xml) {
+		InputSource source = new InputSource(new StringReader(xml));
+
+		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+		String description = "";
+		try{
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			Document document = db.parse(source);
+
+			XPathFactory xpathFactory = XPathFactory.newInstance();
+			XPath xpath = xpathFactory.newXPath();
+			
+
+			description = xpath.evaluate(expression, document);		
+		}catch(Exception e){
+			
+		}
+
+
+		System.out.println("description_" + description);
+		return description;
+	}
+	
+	private static String getDescriptionFromXacml(String xacmlData){
+		//FIXME completely untested. Probably not a good idea to use. UPDATE: kind of tested
+		String openTag = "<Description>";
+		String closeTag = "</Description>";
+		int descIndex = xacmlData.indexOf(openTag);
+		int endDescIndex = xacmlData.indexOf(closeTag);
+		String desc = xacmlData.substring(descIndex+openTag.length(),endDescIndex);
+		return desc;
+	}
+	private final String POLICY_NOTIFICATION = "policy";
+	private final String PDP_NOTIFICATION = "pdp";
+	private final String GROUP_NOTIFICATION = "group";
+	public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, XACMLPapServlet xacmlPapServlet){
+		logger.info("DBDao url: " + url + " has reported an update on "+entityType+" entity "+entityId);		
+		PolicyDBDaoTransaction transaction = this.getNewTransaction();
+		switch(entityType){	
+		
+		case POLICY_NOTIFICATION:
+			try{
+			handleIncomingPolicyChange(url, entityId,extraData);
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")");
+			}
+			break;
+		case PDP_NOTIFICATION:
+			try{
+			handleIncomingPdpChange(url, entityId, transaction);
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")");
+			}
+			break;
+		case GROUP_NOTIFICATION:
+			try{
+			handleIncomingGroupChange(url, entityId, extraData, transaction, xacmlPapServlet);
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")");
+			}
+			break;		
+		}
+		//no changes should be being made in this function, we still need to close
+		transaction.rollbackTransaction();
+	}
+	private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException{
+				
+		GroupEntity groupRecord = null;
+		long groupIdLong = -1;
+		try{
+			groupIdLong = Long.parseLong(groupId);
+		} catch(NumberFormatException e){
+			throw new IllegalArgumentException("groupId "+groupId+" cannot be parsed into a long");
+		}
+		try{
+				groupRecord = transaction.getGroup(groupIdLong);
+		} catch(Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");",e);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");");
+			throw new PAPException("Could not get local group "+groupIdLong);
+		}
+		if(groupRecord == null){
+			throw new PersistenceException("The group record returned is null");
+		}
+		//compare to local fs
+		//does group folder exist
+		EcompPDPGroup localGroup = null;
+		try {
+			localGroup = papEngine.getGroup(groupRecord.getGroupId());
+		} catch (Exception e) {
+			logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+groupId+");",e);
+			//throw new PAPException("Could not get local group "+groupId);
+		}
+		if(localGroup == null && extraData != null){
+			//here we can try to load an old group id from the extraData
+			try{
+				localGroup = papEngine.getGroup(extraData);
+			}catch(Exception e){
+				logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+extraData+");",e);
+			}
+		}
+		if(localGroup != null && groupRecord.isDeleted()){
+			EcompPDPGroup newLocalGroup = null;
+			if(extraData != null){
+			try {
+				newLocalGroup = papEngine.getGroup(extraData);
+			} catch (PAPException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");");
+				//throw new PAPException("Could not get new local group "+newGroupId);
+				
+			}
+			}
+			try {
+				papEngine.removeGroup(localGroup, newLocalGroup);
+			} catch (NullPointerException | PAPException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");");
+				throw new PAPException("Could not remove group "+groupId);
+			}
+		}
+		else if(localGroup == null){
+			//creating a new group
+			try {
+				papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());
+			} catch (NullPointerException | PAPException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());");
+				throw new PAPException("Could not create group "+groupRecord);
+			}
+			try {
+				localGroup = papEngine.getGroup(groupRecord.getGroupId());
+			} catch (PAPException e1) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to get pdp group we just created with papEngine.getGroup(groupRecord.getGroupId());\nAny PDPs or policies in the new group may not have been added",e1);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get pdp group we just created with papEngine.getGroup(groupRecord.getGroupId());\nAny PDPs or policies in the new group may not have been added");
+				return;
+				//throw new PAPException("Could not get group "+groupRecord);
+			}
+			//add possible pdps to group
+			List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId()));
+			for(Object pdpO : pdpsInGroup){
+				PdpEntity pdp = (PdpEntity)pdpO;
+				try {
+					papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());
+				} catch (NullPointerException | PAPException e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());");
+					throw new PAPException("Could not create pdp "+pdp);
+				}
+			}
+			//add possible policies to group (filesystem only, apparently)
+		} else {
+			if(!(localGroup instanceof StdPDPGroup)){
+				throw new PAPException("group is not a StdPDPGroup");
+			}
+			//clone the object
+			//because it will be comparing the new group to its own version
+			StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(),localGroup.isDefaultGroup(),localGroup.getName(),localGroup.getDescription(),((StdPDPGroup)localGroup).getDirectory());
+			localGroupClone.setEcompPdps(localGroup.getEcompPdps());
+			localGroupClone.setPipConfigs(localGroup.getPipConfigs());
+			localGroupClone.setStatus(localGroup.getStatus());			
+			//we are updating a group or adding a policy or changing default
+			//set default if it should be
+			if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){
+				try {
+					papEngine.SetDefaultGroup(localGroup);
+					return;
+				} catch (PAPException e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");");
+					throw new PAPException("Could not set default group to "+localGroupClone);
+				}				
+			}		
+			boolean needToUpdate = false;
+			if(updateGroupPoliciesInFileSystem(localGroupClone,localGroup, groupRecord, transaction)){
+				needToUpdate = true;
+			}
+			if(!stringEquals(localGroupClone.getId(),groupRecord.getGroupId()) || !stringEquals(localGroupClone.getName(),groupRecord.getgroupName())){
+				//changing ids
+				//we do not want to change the id, the papEngine will do this for us, it needs to know the old id
+				localGroupClone.setName(groupRecord.getgroupName());
+				needToUpdate = true;
+			}
+			if(!stringEquals(localGroupClone.getDescription(),groupRecord.getDescription())){
+				localGroupClone.setDescription(groupRecord.getDescription());
+				needToUpdate = true;
+			}
+			if(needToUpdate){
+				try {
+					
+					papEngine.updateGroup(localGroupClone);
+				} catch (PAPException e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");");
+					throw new PAPException("Could not update group "+localGroupClone);
+				}
+			}				
+			
+		}
+		//call command that corresponds to the change that was made
+	}
+	//this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db
+	private boolean updateGroupPoliciesInFileSystem(EcompPDPGroup pdpGroup,EcompPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException{
+		if(!(pdpGroup instanceof StdPDPGroup)){
+			throw new PAPException("group is not a StdPDPGroup");
+		}
+		StdPDPGroup group = (StdPDPGroup)pdpGroup;
+		//this must always be true since we don't explicitly know when a delete is occuring
+		boolean didUpdate = true;
+		HashMap<String,PDPPolicy> currentPolicySet = new HashMap<String,PDPPolicy>(oldPdpGroup.getPolicies().size());
+		HashSet<PDPPolicy> newPolicySet = new HashSet<PDPPolicy>();
+		for(PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()){
+			currentPolicySet.put(pdpPolicy.getId(), pdpPolicy);
+		}
+		for(PolicyEntity policy : groupRecord.getPolicies()){
+			String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
+			if(group.getPolicy(pdpPolicyName) == null){
+				didUpdate = true;
+				if(currentPolicySet.containsKey(pdpPolicyName)){
+					newPolicySet.add(currentPolicySet.get(pdpPolicyName));
+				} else{
+					InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
+					group.copyPolicyToFile(pdpPolicyName,policyStream);
+					((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(policy.getPolicyName()));
+					try {
+						policyStream.close();
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+		if(didUpdate){
+			newPolicySet.addAll(group.getPolicies());
+			group.setPolicies(newPolicySet);
+		}
+		return didUpdate;
+		
+	}
+	private String removeExtensionAndVersionFromPolicyName(String originalPolicyName){
+		String policyName = originalPolicyName;
+		try{
+			policyName = removeFileExtension(policyName);
+			policyName = policyName.substring(0,policyName.lastIndexOf('.'));
+			if(isNullOrEmpty(policyName)){
+				throw new Exception();
+			}
+		} catch(Exception e){
+			policyName = originalPolicyName;
+		}
+		return policyName;
+	}
+	
+	private void handleIncomingPdpChange(String url, String pdpId, PolicyDBDaoTransaction transaction) throws PAPException{
+		//get pdp
+		long pdpIdLong = -1;
+		try{
+			pdpIdLong = Long.parseLong(pdpId);
+		}catch(NumberFormatException e){
+			throw new IllegalArgumentException("pdpId "+pdpId+" cannot be parsed into a long");
+		}
+		PdpEntity pdpRecord = null;
+		try{
+		pdpRecord = transaction.getPdp(pdpIdLong);
+		}catch(Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");",e);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");");
+			throw new PAPException("Could not get local pdp "+pdpIdLong);
+		}
+		if(pdpRecord == null){
+			throw new PersistenceException("The pdpRecord returned is null");
+		}
+		PDP localPdp = null;
+		try {
+			localPdp = papEngine.getPDP(pdpRecord.getPdpId());
+		} catch (PAPException e) {
+			logger.warn("Caught PAPException trying to get local pdp  with papEngine.getPDP("+pdpId+");",e);
+		}
+		if(localPdp != null && pdpRecord.isDeleted()){
+			try {
+				papEngine.removePDP((EcompPDP) localPdp);
+			} catch (PAPException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");");
+				throw new PAPException("Could not remove pdp "+pdpId);
+			}
+		}
+		else if(localPdp == null){
+			//add new pdp
+			//get group
+			
+			EcompPDPGroup localGroup = null;
+			try {
+				localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
+			} catch (PAPException e1) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());",e1);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
+				throw new PAPException("Could not get local group");
+			}			
+			try {
+				papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort());
+			} catch (NullPointerException | PAPException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught PAPException trying to create pdp with papEngine.newPDP("+pdpRecord.getPdpId()+", "+localGroup+", "+pdpRecord.getPdpName()+", "+pdpRecord.getDescription()+", "+pdpRecord.getJmxPort()+");",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp with papEngine.newPDP("+pdpRecord.getPdpId()+", "+localGroup+", "+pdpRecord.getPdpName()+", "+pdpRecord.getDescription()+", "+pdpRecord.getJmxPort()+");");
+				throw new PAPException("Could not create pdp "+pdpRecord);
+			}
+		} else {
+			boolean needToUpdate = false;
+			if(!stringEquals(localPdp.getId(),pdpRecord.getPdpId()) || !stringEquals(localPdp.getName(),pdpRecord.getPdpName())){
+				//again, we don't want to change the id, the papEngine will do this
+				localPdp.setName(pdpRecord.getPdpName());
+				needToUpdate = true;
+			}
+			if(!stringEquals(localPdp.getDescription(),pdpRecord.getDescription())){
+				localPdp.setDescription(pdpRecord.getDescription());
+				needToUpdate = true;
+			}
+			String localPdpGroupId = null;
+					try{
+			localPdpGroupId = papEngine.getPDPGroup((EcompPDP) localPdp).getId();
+					} catch(PAPException e){
+						//could be null or something, just warn at this point
+						logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();",e);
+						//throw new PAPException("Could not get local group");
+					}
+					if(!stringEquals(localPdpGroupId,pdpRecord.getGroup().getGroupId())){
+						EcompPDPGroup newPdpGroup = null;
+						try{
+						newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
+						}catch(PAPException e){
+							//ok, now we have an issue. Time to stop things
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
+							throw new PAPException("Could not get local group");
+						}
+						try{
+						papEngine.movePDP((EcompPDP) localPdp, newPdpGroup);
+						}catch(PAPException e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);");
+							throw new PAPException("Could not move pdp "+localPdp);
+						}
+					}
+			if(((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()){
+				((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort());
+				needToUpdate = true;
+			}
+			if(needToUpdate){
+				try {
+					papEngine.updatePDP((EcompPDP) localPdp);
+				} catch (PAPException e) {
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");");
+					throw new PAPException("Could not update pdp "+localPdp);
+				}
+			}
+		}
+		//compare to local situation
+		//call command to update
+	}
+	private void handleIncomingPolicyChange(String url, String policyId,String oldPathString){
+		EntityManager em = emf.createEntityManager();
+		Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById");
+		getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId));
+		
+		@SuppressWarnings("unchecked")
+		List<PolicyEntity> policies = getPolicyEntityQuery.getResultList();
+		PolicyEntity policy = null;
+		if (policies.size() > 0){
+			policy = policies.get(0);
+		}
+		
+		String policyRepo = buildPolicyScopeDirectory(policy);
+		
+		Path policyPath = Paths.get(policyRepo);
+		String action = "unknown action";
+		try {
+
+			if(policy.isDeleted()){
+				logger.debug("Deleting Policy: " + policy.getPolicyName());
+				action = "delete";
+				Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName());
+				Files.deleteIfExists(newPath);
+				
+				Path subFile = null;
+				
+				if (policy.getConfigurationData()!= null){
+					subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), "Config");
+				}else if(policy.getActionBodyEntity()!= null){
+					subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), "Action");
+				}
+				
+				if(subFile != null){
+					Files.deleteIfExists(subFile);
+				}
+				
+			}else{
+				logger.debug("Updating/Creating Policy: " + policy.getPolicyName());
+				action = "update";
+				Files.createDirectories(policyPath);
+				Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName());
+				Files.deleteIfExists(newPath);
+				if(!isNullOrEmpty(oldPathString)){
+					try{
+						String[] scopeName = getScopeAndNameAndType(oldPathString);
+					Path oldPath = Paths.get(buildPolicyScopeDirectory(scopeName[0]),scopeName[1]);
+					Files.delete(oldPath.toAbsolutePath());
+					}catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Could not delete the old policy before rename: "+oldPathString,e);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy before rename: "+oldPathString);
+					}
+				}
+				Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData()));
+				XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData);		
+				
+				if (policy.getConfigurationData()!= null){
+					if(!isNullOrEmpty(oldPathString)){
+						try{						
+						String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString);
+						String oldConfigFileName = getConfigFile(oldPolicyScopeName[1],oldPolicyScopeName[0],policy.getConfigurationData().getConfigType());
+						Path oldConfigFilePath = getPolicySubFile(oldConfigFileName, "Config");
+						logger.debug("Trying to delete: "+oldConfigFilePath.toString());
+						Files.delete(oldConfigFilePath);						
+						}catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Could not delete the old policy config before rename for policy: "+oldPathString,e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy config before rename for policy: "+oldPathString);
+						}
+					}
+					writePolicySubFile(policy, "Config");
+					
+				}else if(policy.getActionBodyEntity()!= null){
+					if(!isNullOrEmpty(oldPathString)){
+						try{						
+						String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString);
+						String oldActionFileName = getConfigFile(oldPolicyScopeName[1],oldPolicyScopeName[0],ConfigPolicy.JSON_CONFIG);
+						Path oldActionFilePath = getPolicySubFile(oldActionFileName, "Action");
+						logger.debug("Trying to delete: "+oldActionFilePath.toString());
+						Files.delete(oldActionFilePath);						
+						}catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Could not delete the old policy action body before rename for policy: "+oldPathString,e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy action body before rename for policy: "+oldPathString);
+						}
+					}
+					writePolicySubFile(policy, "Action");
+				}
+					
+			}
+		} catch (IOException e1) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Error occurred while performing [" + action + "] of Policy File: " +  policy.getPolicyName(), e1);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while performing [" + action + "] of Policy File: " +  policy.getPolicyName());
+		}	
+	}
+	
+	//FIXME error correcting and logs
+	private void createGroupsFromDatabase(){
+		//get list of groups
+		boolean foundDefault = false;
+		//need to avoid infinite loop, just in case
+		boolean alreadyRunAdd = false;
+		while(!foundDefault){			
+		
+		EntityManager em = emf.createEntityManager();
+		Query getGroups = em.createQuery("SELECT g FROM GroupEntity g WHERE g.deleted=:deleted");
+		getGroups.setParameter("deleted", false);
+		List<?> groups = getGroups.getResultList();
+		em.close();
+		//make a folder for each group in pdps folders
+		Path pdpsPath = Paths.get("pdps");
+		try {
+			FileUtils.forceDelete(pdpsPath.toFile());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		try {
+			FileUtils.forceMkdir(pdpsPath.toFile());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		Properties propertyFileProperties = new Properties();
+		String groupList = "";
+		String defaultGroup = "";
+		for(Object o : groups){
+			GroupEntity group = (GroupEntity)o;
+			Path groupPath = Paths.get(pdpsPath.toString(), group.getGroupId());
+			try {
+				FileUtils.forceMkdir(groupPath.toFile());
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			Properties policyProperties = new Properties();
+			String rootPolicies = "";
+			for(PolicyEntity policy : group.getPolicies()){
+				Path newPolicyPath = Paths.get(groupPath.toString(),getPdpPolicyName(policy.getPolicyName(),policy.getScope()));
+				File newPolicyFile = newPolicyPath.toFile();
+				try {
+					newPolicyFile.createNewFile();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				try {
+					FileOutputStream policyFileStream = new FileOutputStream(newPolicyFile);
+						policyFileStream.write(policy.getPolicyData().getBytes("UTF-8"));
+					policyFileStream.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				policyProperties.setProperty(getPdpPolicyName(policy.getPolicyName(),policy.getScope())+".name",removeExtensionAndVersionFromPolicyName(policy.getPolicyName()));
+				rootPolicies += ",".concat(getPdpPolicyName(policy.getPolicyName(),policy.getScope()));
+			}
+			Path xacmlPolicyPropertiesPath = Paths.get(groupPath.toString(),"xacml.policy.properties");
+			File xacmlPolicyPropertiesFile = xacmlPolicyPropertiesPath.toFile();
+			if(rootPolicies.length() > 0){
+				rootPolicies = rootPolicies.substring(1);
+			}
+			policyProperties.setProperty("xacml.referencedPolicies", "");
+			policyProperties.setProperty("xacml.rootPolicies", rootPolicies);
+			
+			try {
+				xacmlPolicyPropertiesFile.createNewFile();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			try {
+				FileOutputStream xacmlPolicyPropertiesFileStream = new FileOutputStream(xacmlPolicyPropertiesFile);
+				//xacmlPolicyPropertiesFileStream.write(xacmlPolicyProperties.getBytes("UTF-8"));
+				policyProperties.store(xacmlPolicyPropertiesFileStream, "");
+				xacmlPolicyPropertiesFileStream.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+			em = emf.createEntityManager();
+			Query getPdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group AND p.deleted=:deleted");
+			getPdpsQuery.setParameter("group", group);
+			getPdpsQuery.setParameter("deleted", false);
+			List<?> pdps = getPdpsQuery.getResultList();
+			em.close();			
+			String pdpLine = "";
+			for(Object o2 : pdps){
+				PdpEntity pdp = (PdpEntity)o2;
+				pdpLine += ",".concat(pdp.getPdpId());
+				propertyFileProperties.setProperty(pdp.getPdpId()+".description",pdp.getDescription());
+				propertyFileProperties.setProperty(pdp.getPdpId()+".jmxport",String.valueOf(pdp.getJmxPort()));
+				propertyFileProperties.setProperty(pdp.getPdpId()+".name",pdp.getPdpName());
+			}
+			if(pdpLine.length() > 0){
+				pdpLine = pdpLine.substring(1);
+			}
+			propertyFileProperties.setProperty(group.getGroupId()+".description", group.getDescription());
+			propertyFileProperties.setProperty(group.getGroupId()+".name", group.getgroupName());
+			propertyFileProperties.setProperty(group.getGroupId()+".pdps",pdpLine);
+			groupList += ",".concat(group.getGroupId());
+			if(group.isDefaultGroup()){
+				defaultGroup = group.getGroupId();
+				foundDefault = true;
+			}
+		}
+		if(!foundDefault && !alreadyRunAdd){
+			alreadyRunAdd = true;
+			//add default group to db
+			try{
+			em = emf.createEntityManager();
+			em.getTransaction().begin();
+			GroupEntity newDefaultGroup = new GroupEntity();
+			em.persist(newDefaultGroup);
+			newDefaultGroup.setDescription("The default group where new PDP's are put.");
+			newDefaultGroup.setGroupId("default");
+			newDefaultGroup.setGroupName("default");
+			newDefaultGroup.setDefaultGroup(true);
+			newDefaultGroup.setCreatedBy("automaticallyAdded");
+			newDefaultGroup.setModifiedBy("automaticallyAdded");
+			em.flush();
+			em.getTransaction().commit();		
+			continue;
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Could not add a new default group to the database",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not add a new default group to the database");
+			}
+		}
+		
+		Path xacmlPropertiesPath = Paths.get(pdpsPath.toString(),"xacml.properties");
+		File xacmlPropertiesFile = xacmlPropertiesPath.toFile();
+		if(groupList.length()>0){
+			groupList = groupList.substring(1);
+		}
+		propertyFileProperties.setProperty("xacml.pap.groups",groupList);
+		propertyFileProperties.setProperty("xacml.pap.groups.default",defaultGroup);
+		try {
+			xacmlPropertiesFile.createNewFile();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		try {
+			FileOutputStream xacmlPropertiesFileStream = new FileOutputStream(xacmlPropertiesFile);
+			//xacmlPropertiesFileStream.write(fileContents.getBytes("UTF-8"));
+			propertyFileProperties.store(xacmlPropertiesFileStream, "");
+			xacmlPropertiesFileStream.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		//if we get this far down, something went wrong and we don't want to get stuck in the loop
+		foundDefault = true;
+		}
+		//put policies in group folder
+		//create xacml.policy.properties in each folder with list of policies in that folder
+		//get list of pdps
+		//create xacml.properties with list of groups and pdps and other info
+	}
+
+	
+	//FIXME error checking and logging
+	private String getPdpPolicyName(String name, String scope){
+		String finalName = "";
+		finalName += scope;
+		finalName += ".";
+		finalName += removeFileExtension(name);
+		finalName += ".xml";
+		return finalName;
+	}
+	private String removeFileExtension(String fileName){
+		return fileName.substring(0, fileName.lastIndexOf('.'));
+	}
+	
+	private String buildPolicyScopeDirectory(PolicyEntity policy){
+		String repo = buildPolicyDirectory();
+
+		String policyScope = policy.getScope();
+		if(policyScope == null){
+			policyScope = "";
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
+			PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
+		} else {
+			policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator());	
+		}
+		if(policyScope == null){
+			policyScope = "";
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
+			PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
+		}
+		if(repo == null){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank.");
+			PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank.");
+			repo = "";
+		}
+		Path returnPath = Paths.get(repo + FileSystems.getDefault().getSeparator() + policyScope);
+		if(returnPath !=  null){
+			return returnPath.toString();
+		} else {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("buildPolicyScopeDirectory("+policy+") computed null path");
+			PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank.");
+			return "";
+		}
+
+
+	}
+	private String buildPolicyScopeDirectory(String policyScope){
+		String repo = buildPolicyDirectory();		
+		policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator());
+		return repo + FileSystems.getDefault().getSeparator() + policyScope;
+		
+	}
+	
+	private static String buildPolicyDirectory(){
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), getDefaultWorkspace());
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+		
+    	/*
+    	 * Getting and Setting the parent path for Admin Console use when reading the policy files
+    	 */
+    	//domain chosen by the client to store the policy action files 
+    	//String domain = policy.getDomainDir();
+    	    	   
+    	
+    		
+    	//getting the fullpath of the gitPath and convert to string
+    	String policyDir = gitPath.toAbsolutePath().toString();
+    	
+
+		if(policyDir.contains("\\")){
+			policyDir = policyDir.replace("XACML-PAP-REST", "XACML-PAP-ADMIN");
+		}else{
+			if (policyDir.contains("pap")){
+				policyDir = policyDir.replace("pap", "console");
+			}
+		}
+    	logger.debug("policyDir: " + policyDir);
+		return policyDir;
+	}
+	
+	private Path getPolicySubFile(String filename, String subFileType){
+		logger.debug("getPolicySubFile(" + filename + ", " + subFileType + ")");
+		Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), subFileType);
+		File file = null;
+		
+		filename = FilenameUtils.removeExtension(filename);
+		
+		for(File tmpFile : filePath.toFile().listFiles()){
+			if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)){
+				file = tmpFile;
+			}
+		}
+		
+		Path finalPath = null;
+		if (file!= null){
+			finalPath = Paths.get(file.getAbsolutePath());
+		}
+		
+		logger.debug("end of getPolicySubFile: " + finalPath);
+		return finalPath;	
+	}
+		
+	private boolean writePolicySubFile(PolicyEntity policy, String policyType){
+		logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + "]");
+		String type = null;
+		String subTypeName = null;
+		String subTypeBody = null;
+		if (policyType.equalsIgnoreCase("config")){
+			type = "Config";
+			subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName());
+			subTypeBody = policy.getConfigurationData().getConfigBody();
+			
+			String configType = policy.getConfigurationData().getConfigType();
+			
+			
+			if (configType != null) {
+				if (configType.equals(JSON_CONFIG)) {
+					subTypeName = subTypeName + ".json";
+				}
+				if (configType.equals(XML_CONFIG)) {
+					subTypeName = subTypeName + ".xml";
+				}
+				if (configType.equals(PROPERTIES_CONFIG)) {
+					subTypeName = subTypeName + ".properties";
+				}
+				if (configType.equals(OTHER_CONFIG)) {
+					subTypeName = subTypeName + ".txt";
+				}
+			}
+			
+		}else if (policyType.equalsIgnoreCase("action")){
+			type = "Action";
+			subTypeName = policy.getActionBodyEntity().getActionBodyName();
+			subTypeBody = policy.getActionBodyEntity().getActionBody();
+			
+			
+		}
+		Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type);
+
+		if(subTypeBody == null){
+			subTypeBody = "";
+		}
+		boolean success = false;
+			try {
+				Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName));
+				File file = Paths.get(filePath.toString(),subTypeName).toFile();
+				file.createNewFile();
+				FileWriter fileWriter = new FileWriter(file, false); // false to overwrite
+				fileWriter.write(subTypeBody);
+				fileWriter.close();
+				success = true;
+
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Exception occured while creating Configuration File for Policy : " + policy.getPolicyName(), e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName());
+			}					
+		
+		return success;
+		
+	}
+	
+	private String getPolicySubType(String filename){
+		String type = null;
+	
+		if (filename != null) {
+			if (FilenameUtils.getExtension(filename).equalsIgnoreCase("json")) {
+				type = ConfigPolicy.JSON_CONFIG;
+			}
+			if (FilenameUtils.getExtension(filename).equalsIgnoreCase("xml")) {
+				type = ConfigPolicy.XML_CONFIG;
+			}
+			if (FilenameUtils.getExtension(filename).equalsIgnoreCase("properties")) {
+				type = ConfigPolicy.PROPERTIES_CONFIG;
+			}
+			if (FilenameUtils.getExtension(filename).equalsIgnoreCase("txt")) {
+				type = ConfigPolicy.OTHER_CONFIG;
+			}
+		}
+			
+		return type;
+		
+	}
+	
+	
+	private  void convertFileToDBEntry(Path path){
+		logger.info("convertFileToDBEntry");
+		
+		if(path.toString().contains(".git")){
+			return;
+		}
+		
+		String filename = path.getFileName().toString();
+		if (filename.contains(".svnignore")){
+			return;
+		}
+
+		String[] scopeAndName = getScopeAndNameAndType(path.toString());
+		
+		if(scopeAndName == null){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + path.toString() + " is null!");
+			PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + path.toString() + " is null!");
+			return;
+		}
+
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		
+		PolicyEntity policy = new PolicyEntity();
+		em.persist(policy);
+		String policyScope = scopeAndName[0];
+		String policyName = scopeAndName[1];
+		policy.setScope(policyScope);
+		policy.setPolicyName(policyName);
+		policy.setCreatedBy(AUDIT_USER);
+		policy.setModifiedBy(AUDIT_USER);
+
+		String newScope = policyScope.replace(".", File.separator);
+		String newName = FilenameUtils.removeExtension(policyName);
+		int version = 1;
+		try{
+			//we want the last index +1 because we don't want the dot
+			version = Integer.parseInt(newName.substring(newName.lastIndexOf(".")+1)); 
+		} catch(Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Could not get the policy version number from "+newName);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get the policy version number from "+newName);
+		}
+		newName = newScope + File.separator + newName.substring(0, newName.lastIndexOf("."));	
+
+		Query query = em.createNamedQuery("PolicyVersion.findByPolicyName");
+		query.setParameter("pname", newName);
+		
+		List<?> result = query.getResultList();
+		PolicyVersion versionEntity = null;
+		
+		if (!result.isEmpty()) {
+			logger.info("Result is not empty");
+			versionEntity = (PolicyVersion) result.get(0);
+			int highestVersion = Math.max(versionEntity.getHigherVersion(),version);
+			versionEntity.setHigherVersion(highestVersion);
+			versionEntity.setActiveVersion(highestVersion);
+		}else{
+			logger.info("result is empty");
+			Calendar calendar = Calendar.getInstance();
+			Timestamp createdDate = new Timestamp(calendar.getTime().getTime());
+			
+			versionEntity = new PolicyVersion();
+			em.persist(versionEntity);
+			versionEntity.setPolicyName(newName);
+			versionEntity.setHigherVersion(version);
+			versionEntity.setActiveVersion(version);
+			versionEntity.setCreatedBy(AUDIT_USER);
+			versionEntity.setModifiedBy(AUDIT_USER);
+			versionEntity.setCreatedDate(createdDate);
+			versionEntity.setModifiedDate(createdDate);
+		}
+		
+		
+		try {
+			String policyContent = new String(Files.readAllBytes(path));
+			policy.setDescription(getElementFromXMLString("/Description", policyContent));
+			policy.setPolicyData(policyContent);
+		} catch (IOException e1) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("convertFileToDBEntry error settingPolicyData: " + e1.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData");
+			em.getTransaction().rollback();
+			em.close();
+			return;
+		}
+		
+		if((scopeAndName[2].equalsIgnoreCase("Config"))){
+			String scopeName = scopeAndName[0] + "." + scopeAndName[1];
+			Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]);
+			try {
+				String content = new String(Files.readAllBytes(subFilePath));
+				String configName = subFilePath.getFileName().toString();
+				ConfigurationDataEntity configData = new ConfigurationDataEntity();
+				em.persist(configData);
+				configData.setConfigurationName(subFilePath.getFileName().toString());
+				configData.setConfigBody(content);
+				configData.setConfigType(getPolicySubType(configName));
+				configData.setCreatedBy(AUDIT_USER);
+				configData.setModifiedBy(AUDIT_USER);
+				policy.setConfigurationData(configData);
+				
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("convertFileToDBEntry error for Config policy: " + e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Config policy");
+				em.getTransaction().rollback();
+				em.close();
+				return;
+			}
+		}else if(scopeAndName[2].equalsIgnoreCase("Action")){
+			String scopeName = scopeAndName[0] + "." + scopeAndName[1];
+			Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]);
+			try {
+				String content = new String(Files.readAllBytes(subFilePath));
+				ActionBodyEntity actionBody = new ActionBodyEntity();
+				em.persist(actionBody);
+				actionBody.setActionBodyName(subFilePath.getFileName().toString());
+				actionBody.setActionBody(content);
+				actionBody.setCreatedBy(AUDIT_USER);
+				actionBody.setModifiedBy(AUDIT_USER);
+				policy.setActionBodyEntity(actionBody);
+				
+			} catch (Exception e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("convertFileToDBEntry error for Action policy: " + e.getMessage());
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Action policy");
+				em.getTransaction().rollback();
+				em.close();
+				return;
+			}			
+		}
+		logger.debug("convertFileToDBEntry commit transaction");
+		em.getTransaction().commit();
+		em.close();
+	}
+	
+	private void deleteAllPolicyTables(){
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		Query deletePolicyEntityTableUpdate = em.createNamedQuery("PolicyEntity.deleteAll");
+		Query deleteActionBodyEntityTableUpdate = em.createNamedQuery("ActionBodyEntity.deleteAll");
+		Query deleteConfigurationDataEntityTableUpdate = em.createNamedQuery("ConfigurationDataEntity.deleteAll");
+		Query deletePolicyVersionEntityTableUpdate = em.createNamedQuery("PolicyVersion.deleteAll");
+		deletePolicyEntityTableUpdate.executeUpdate();
+		deleteActionBodyEntityTableUpdate.executeUpdate();
+		deleteConfigurationDataEntityTableUpdate.executeUpdate();
+		deletePolicyVersionEntityTableUpdate.executeUpdate();
+		em.getTransaction().commit();
+		em.close();
+		
+	}
+		
+	public void auditLocalDatabase(PAPPolicyEngine papEngine2){
+		logger.debug("PolicyDBDao.auditLocalDatabase() is called");
+		Path webappsPath = Paths.get(buildPolicyDirectory());
+		try{
+			deleteAllGroupTables();
+			deleteAllPolicyTables();
+			Files.createDirectories(webappsPath);
+			Files.walk(webappsPath).filter(Files::isRegularFile).forEach(this::convertFileToDBEntry);
+			auditGroups(papEngine2);
+		} catch(Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("auditLocalDatabase() error: " + e.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "auditLocalDatabase() error");
+			e.printStackTrace();
+		}		
+	}
+	
+	/**
+	 * Audits and loads the local file system to match the database version.
+	 */
+	@SuppressWarnings("unchecked")
+	public void auditLocalFileSystem(){
+		logger.debug("PolicyDBDau.auditLocalFileSystem() is called");
+
+		Path webappsPath = Paths.get(buildPolicyDirectory());
+		Path configFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Config");
+		Path actionFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Action");
+		try {
+			Files.createDirectories(configFilesPath);
+			Files.createDirectories(actionFilesPath);
+			FileUtils.cleanDirectory(actionFilesPath.toFile());
+			FileUtils.cleanDirectory(configFilesPath.toFile());
+			if (webappsPath.toFile().exists()){
+				FileUtils.cleanDirectory(webappsPath.toFile());
+			}
+			Path repoWithScope = Paths.get(webappsPath.toString(), XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DOMAIN));
+			Files.createDirectories(repoWithScope);
+		} catch (IOException e2) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("Error occurred while creating / clearing Config and Policy filesystem directories", e2);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Error occurred while creating / clearing Config and Policy filesystem directories");
+		}
+
+		List<PolicyEntity> policyEntityList;
+		try{
+			EntityManager em = emf.createEntityManager();
+			Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findAllByDeletedFlag");
+			getPolicyEntitiesQuery.setParameter("deleted", false);
+			policyEntityList = getPolicyEntitiesQuery.getResultList();
+		} catch(Exception e){
+			policyEntityList = new LinkedList<PolicyEntity>();
+		}
+
+		for (PolicyEntity policy: policyEntityList){
+			String name = "";
+			try {
+				if (!policy.isDeleted()){
+					name = policy.getPolicyName();				
+					String scope = policy.getScope();
+
+					scope = scope.replace(".", "//");
+					if (policy.getConfigurationData()!=null){
+						writePolicySubFile(policy, "Config");
+					}	
+					else if(policy.getActionBodyEntity()!=null){
+						writePolicySubFile(policy, "Action");
+					}
+
+
+					Path fileLocation = Paths.get(webappsPath.toString(), scope);
+
+					Files.createDirectories(fileLocation);
+					Path newPath = Paths.get(fileLocation.toString(), name);
+					Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData()));
+					XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData);		
+				}
+			} catch (Exception e1) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Error occurred while creating Policy File: " + name, e1);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while creating Policy File: " + name);
+			}		
+		}	
+		createGroupsFromDatabase();
+	}
+	
+	public void deleteAllGroupTables(){
+		logger.debug("PolicyDBDao.deleteAllGroupTables() called");
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+
+		Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll");
+		deletePdpEntityEntityTableUpdate.executeUpdate();
+		
+		Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll");
+		deleteGroupEntityTableUpdate.executeUpdate();
+		
+		em.getTransaction().commit();
+		em.close();
+	}
+	
+	@SuppressWarnings("unchecked")
+	public void auditGroups(PAPPolicyEngine papEngine2){
+		logger.debug("PolicyDBDao.auditGroups() called");
+		
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		final String AUDIT_STR = "Audit";
+		try{
+
+			Set<EcompPDPGroup> groups = papEngine2.getEcompPDPGroups();
+			
+			for (EcompPDPGroup grp : groups){
+				try{
+				GroupEntity groupEntity = new GroupEntity();
+				em.persist(groupEntity);
+				groupEntity.setGroupName(grp.getName());
+				groupEntity.setDescription(grp.getDescription());
+				groupEntity.setDefaultGroup(grp.isDefaultGroup());
+				groupEntity.setCreatedBy(AUDIT_STR);
+				groupEntity.setGroupId(createNewPDPGroupId(grp.getId()));
+				groupEntity.setModifiedBy(AUDIT_STR);
+				Set<EcompPDP> pdps =  grp.getEcompPdps();				
+				
+				for(EcompPDP pdp : pdps){
+					PdpEntity pdpEntity = new PdpEntity();
+					em.persist(pdpEntity);
+					pdpEntity.setGroup(groupEntity);
+					pdpEntity.setJmxPort(pdp.getJmxPort());
+					pdpEntity.setPdpId(pdp.getId());
+					pdpEntity.setPdpName(pdp.getName());
+					pdpEntity.setModifiedBy(AUDIT_STR);
+					pdpEntity.setCreatedBy(AUDIT_STR);
+					
+				}
+				
+				Set<PDPPolicy> policies = grp.getPolicies();
+				
+				for(PDPPolicy policy : policies){
+					try{
+					String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId());
+					List<PolicyEntity> policyEntityList;
+					Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope");
+					getPolicyEntitiesQuery.setParameter("name", stringArray[0]);
+					getPolicyEntitiesQuery.setParameter("scope", stringArray[1]);
+					
+					policyEntityList = getPolicyEntitiesQuery.getResultList();
+					PolicyEntity policyEntity = null;
+					if(policyEntityList.size() < 1){
+						policyEntity = addPolicyThatOnlyExistsInPdpGroup(policy.getId(),Paths.get("pdps",grp.getId(),policy.getId()),em);
+					} else {
+						policyEntity = policyEntityList.get(0);
+					}
+					if(policyEntity != null){
+						groupEntity.addPolicyToGroup(policyEntity);
+					}
+					}catch(Exception e2){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("ERROR: " + e2);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Exception auditGroups inner catch");
+					}
+				}
+				}catch(Exception e1){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("ERROR: " + e1);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Exception auditGroups middle catch");
+				}
+			}
+		}catch(Exception e){
+			em.getTransaction().rollback();
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("ERROR: " + e);
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception auditGroups outer catch");
+			em.close();
+			return;
+		}
+		
+		em.getTransaction().commit();
+		em.close();
+		
+	}
+	
+	private PolicyEntity addPolicyThatOnlyExistsInPdpGroup(String polId, Path path,EntityManager em){
+		String filename = path.getFileName().toString();
+		if (filename.contains(".svnignore")){
+			return null;
+		}
+
+		String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(polId);
+		
+		if(scopeAndName == null){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + polId.toString() + " is null!");
+			PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + polId.toString() + " is null!");
+			return null;
+		}
+
+		
+		PolicyEntity policy = new PolicyEntity();
+		em.persist(policy);
+		String policyScope = scopeAndName[1];
+		String policyName = scopeAndName[0];
+		policy.setScope(policyScope);
+		policy.setPolicyName(policyName);
+		policy.setCreatedBy(AUDIT_USER);
+		policy.setModifiedBy(AUDIT_USER);
+		policy.setDeleted(true);
+		
+		try {
+			String policyContent = new String(Files.readAllBytes(path));
+			policy.setDescription(getElementFromXMLString("/Description", policyContent));
+			policy.setPolicyData(policyContent);
+			em.flush();
+			//em.getTransaction().commit();
+		} catch (IOException e1) {
+			// TODO Auto-generated catch block
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error("convertFileToDBEntry error settingPolicyData: " + e1.getMessage());
+			PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData");
+			return null;
+		}
+		//em.close();
+		return policy;
+	}
+	
+	private String getConfigFile(String filename, String scope, PolicyRestAdapter policy){
+		if(policy == null){
+			return getConfigFile(filename, scope, (String)null);
+		}
+		return getConfigFile(filename, scope, policy.getConfigType());
+	}
+	//copied from ConfigPolicy.java and modified
+	// Here we are adding the extension for the configurations file based on the
+	// config type selection for saving.
+	private String getConfigFile(String filename, String scope, String configType) {
+		logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile("+filename+", "+scope+", "+configType+") called");
+		filename = FilenameUtils.removeExtension(filename);
+//		if (filename.endsWith(".xml")) {
+//			filename = filename.substring(0, filename.length() - 4);
+//		}
+		String id = configType;
+
+		if (id != null) {
+			if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) {
+				filename = filename + ".json";
+			}
+			if (id.equals(ConfigPolicy.XML_CONFIG)) {
+				filename = filename + ".xml";
+			}
+			if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) {
+				filename = filename + ".properties";
+			}
+			if (id.equals(ConfigPolicy.OTHER_CONFIG)) {
+				filename = filename + ".txt";
+			}
+		}
+		return scope + "." + filename;
+	}
+	
+	/**
+	 * Constructs the file name of a policy.
+	 * @param policy The name of a policy (ex: mypolicy1)
+	 * @return The file name of the policy (ex: Config_mypolicy1.xml)
+	 * @deprecated
+	 */
+	@SuppressWarnings("unused")
+	private String getName(PolicyRestAdapter policy){
+		logger.debug("getName(PolicyRestAdapter policy) as getName("+policy+") called");
+		String namePrefix = "";
+		if(policy.getPolicyType().contains("Config")){
+			namePrefix = namePrefix.concat(policy.getPolicyType());
+			if(policy.getConfigType().contains("Firewall")){
+				namePrefix = namePrefix.concat("_FW");
+			}
+		}
+		String concats =  namePrefix + "_" +policy.getPolicyName() + ".xml";
+		return concats;
+	}
+	
+	private String stripPolicyName(String policyFileName){
+		String policyName = policyFileName;
+		try{
+			policyName = policyName.substring(policyName.indexOf('_')+1);
+			policyName = removeFileExtension(policyName);
+		}catch(Exception e){						
+			throw new IllegalArgumentException("Could not get name out of policy file name: "+policyName);						
+		}
+		return policyName;
+	}
+	//FIXME error check, logs
+	private String[] getNameScopeAndVersionFromPdpPolicy(String fileName){
+		String[] splitByDots = fileName.split("\\.");
+		if(splitByDots.length < 3){
+			//throw something
+			return null;
+		}
+		String policyName = splitByDots[splitByDots.length-3];
+		String version = splitByDots[splitByDots.length-2];
+		//policy names now include version
+		policyName += "."+version +".xml";
+		String scope = "";
+		for(int i=0;i<splitByDots.length-3;i++){
+			scope += ".".concat(splitByDots[i]);
+		}
+		//remove the first dot
+		if(scope.length() > 0){
+			scope = scope.substring(1);
+		}
+		String[] returnArray = new String[3];
+		returnArray[0] = policyName;
+		returnArray[2] = version;
+		returnArray[1] = scope;
+		return returnArray;
+	}
+	
+	/**
+	 * Constructs the complete repository path based on the properties files
+	 * @return The repository path
+	 */
+	public static String getGitPath(){
+		logger.debug("getGitPath() as getGitPath() called");
+		Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
+		Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
+		Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
+		logger.debug("after gitPath: " + gitPath);
+		return gitPath.toString();
+	}
+	
+	//copied from StdEngine.java
+	public static String createNewPDPGroupId(String name) {
+		String id = name;
+		// replace "bad" characters with sequences that will be ok for file names and properties keys.
+		id = id.replace(" ", "_sp_");
+		id = id.replace("\t", "_tab_");
+		id = id.replace("\\", "_bksl_");
+		id = id.replace("/", "_sl_");
+		id = id.replace(":", "_col_");
+		id = id.replace("*", "_ast_");
+		id = id.replace("?", "_q_");
+		id = id.replace("\"", "_quo_");
+		id = id.replace("<", "_lt_");
+		id = id.replace(">", "_gt_");
+		id = id.replace("|", "_bar_");
+		id = id.replace("=", "_eq_");
+		id = id.replace(",", "_com_");
+		id = id.replace(";", "_scom_");
+
+		return id;
+	}
+	
+	/**
+	 * Checks if any of the given strings are empty or null
+	 * @param strings One or more Strings (or nulls) to check if they are null or empty
+	 * @return true if one or more of the given strings are empty or null
+	 */
+	private static boolean isNullOrEmpty(String... strings){
+		for(String s : strings){
+			if(!(s instanceof String)){
+				return true;
+			}
+			if(s.equals("")){
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Computes the scope, name, and type of a policy based on its file path
+	 * @param path The file path of the policy (including the xml policy file)
+	 * @return A string array of size 3. 1: the scope of the policy  2: the name of the policy (Config_mypol.xml) 3: the type (Config). Or, null if the path can not be parsed.
+	 */
+	private static String[] getScopeAndNameAndType(String path){
+		logger.debug("getScopeAndNameAndType(String path) as getScopeAndNameAndType("+path+") called");
+		if(path == null){
+			
+		}
+		String gitPath  = getGitPath();
+
+		ArrayList<String> gitPathParts = new ArrayList<String>();
+		Iterator<?> gitPathIterator = Paths.get(gitPath).iterator();
+		while(gitPathIterator.hasNext()){
+			gitPathParts.add(gitPathIterator.next().toString());
+		}
+		for(int i=0;i<gitPathParts.size();i++){
+			Path testGitPath = Paths.get("");
+			for(int j=i;j<gitPathParts.size();j++){
+				testGitPath = Paths.get(testGitPath.toString(),gitPathParts.get(j));
+			}
+			if(path.contains(testGitPath.toString())){
+				gitPath = testGitPath.toString();
+				break;
+			}
+		}
+		if(gitPath == null){
+			logger.debug("gitPath is null.  Returning");
+			return null;
+		}
+		if(gitPath.length() >= path.length()){
+			logger.debug("gitPath length(): " + gitPath.length() + ">= path.length(): " + path.length() + ".  Returning null");
+			return null;
+		}
+		String scopeAndName = path.substring(path.indexOf(gitPath)+gitPath.length());
+	
+		logger.debug("scopeAndName: " + scopeAndName);
+		String policyType = null;
+		String[] policyTypes = {"Config_","Action_","Decision_"};
+		for(String pType : policyTypes){
+			if(scopeAndName.contains(pType)){
+				policyType = pType;
+			}
+		}
+		if(policyType == null){
+			return null;
+		}
+		String scope = scopeAndName.substring(0,scopeAndName.indexOf(policyType));
+		String name = scopeAndName.substring(scopeAndName.indexOf(policyType), scopeAndName.length());
+		scope = scope.replace('\\', '.');
+		scope = scope.replace('/', '.');
+		if(scope.length()<1){
+			return null;
+		}
+		if(scope.charAt(0) == '.'){
+			if(scope.length() < 2){
+				logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2. " + "| scope.charAt(0)==.");
+				return null;
+			}
+			scope = scope.substring(1);
+		}
+		if(scope.charAt(scope.length()-1) == '.'){
+			if(scope.length() < 2){
+				logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2" + "| scope.charAt(scope.length()-1)==.");
+				return null;
+			}
+			scope = scope.substring(0,scope.length()-1);
+		}
+		if(name.length()<1){
+			logger.debug("getScopeAndNameAndType error: name.length()<1");
+			return null;
+		}
+		if(name.charAt(0) == '.'){
+			if(name.length() < 2){
+				logger.debug("getScopeAndNameAndType error: " + name.length() + " < 2. " + "| scope.charAt(0)==.");
+				return null;
+			}
+			name = name.substring(1);
+		}
+		String[] returnArray = new String[3];
+		returnArray[0] = scope;
+		returnArray[1] = name;
+		//remove the underscore and return it
+		returnArray[2] = policyType.substring(0, policyType.length()-1);
+		return returnArray;
+	}
+
+	
+	private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction {
+		private EntityManager em;
+		private final Object emLock = new Object();
+		long policyId;
+		long groupId;
+		long pdpId;
+		String newGroupId;
+		private boolean operationRun = false;
+		private final Thread transactionTimer;
+		
+		private PolicyDBDaoTransactionInstance(){
+			//call the constructor with arguments
+			this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)),
+					Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)));
+		}
+		//timeout is how long the transaction can sit before rolling back
+		//wait time is how long to wait for the transaction to start before throwing an exception
+		private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime){
+			if(logger.isDebugEnabled()){
+				logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:"
+					+ "\n   transactionTimeout = " + transactionTimeout
+					+ "\n   transactionWaitTime = " + transactionWaitTime + "\n\n");
+			}
+			this.em = emf.createEntityManager();
+			policyId = -1;
+			groupId = -1;
+			pdpId = -1;
+			newGroupId = null;
+			synchronized(emLock){
+				try{
+					startTransactionSynced(this.em,transactionWaitTime);
+				} catch(Exception e){
+					throw new PersistenceException("Could not lock transaction within "+transactionWaitTime+" milliseconds");
+				}
+			}
+			class TransactionTimer implements Runnable {
+
+				private int sleepTime;
+				public TransactionTimer(int timeout){
+					this.sleepTime = timeout;
+				}
+				@Override
+				public void run() {
+					if(logger.isDebugEnabled()){
+						Date date= new java.util.Date();
+						logger.debug("\n\nTransactionTimer.run() - SLEEPING: "
+								+ "\n   sleepTime (ms) = " + sleepTime 
+								+ "\n   TimeStamp = " + date.getTime()
+								+ "\n\n");
+					}
+					try {
+						Thread.sleep(sleepTime);
+					} catch (InterruptedException e) {
+						//probably, the transaction was completed, the last thing we want to do is roll back
+						if(logger.isDebugEnabled()){
+							Date date= new java.util.Date();
+							logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: "
+									+ "\n   TimeStamp = " + date.getTime()
+									+ "\n\n");
+						}
+						return;
+					}
+					if(logger.isDebugEnabled()){
+						Date date= new java.util.Date();
+						logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: "
+								+ "\n   TimeStamp = " + date.getTime()
+								+ "\n\n");
+					}
+					rollbackTransaction();					
+				}
+				
+			}
+			
+			transactionTimer = new Thread(new TransactionTimer(transactionTimeout),"transactionTimerThread");
+			transactionTimer.start();
+			
+
+		}
+
+		private void checkBeforeOperationRun(){
+			checkBeforeOperationRun(false);
+		}
+		private void checkBeforeOperationRun(boolean justCheckOpen){
+			if(!isTransactionOpen()){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("There is no transaction currently open");
+				PolicyLogger.error("There is no transaction currently open");
+				throw new IllegalStateException("There is no transaction currently open");
+			}
+			if(operationRun && !justCheckOpen){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("An operation has already been performed and the current transaction should be committed");
+				PolicyLogger.error("An operation has already been performed and the current transaction should be committed");
+				throw new IllegalStateException("An operation has already been performed and the current transaction should be committed");
+			}
+			operationRun = true;
+		}
+		@Override
+		public void commitTransaction() {
+			synchronized(emLock){
+				logger.debug("commitTransaction() as commitTransaction() called");
+				if(!isTransactionOpen()){
+					logger.warn("There is no open transaction to commit");
+					//throw new IllegalStateException("There is no open transaction to commit");
+					try{
+					em.close();
+					} catch(Exception e){
+						e.printStackTrace();
+					}
+					return;
+				}
+				try{
+					em.getTransaction().commit();
+				} catch(RollbackException e){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught RollbackException on em.getTransaction().commit()",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught RollbackException on em.getTransaction().commit()");
+					throw new PersistenceException("The commit failed. Message:\n"+e.getMessage());
+				}
+				em.close();
+				//FIXME need to revisit
+				if(policyId >= 0){
+					
+					if(newGroupId != null){
+						try{
+							notifyOthers(policyId,POLICY_NOTIFICATION,newGroupId);
+						} catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")");
+						}
+					} else {
+						try{
+							notifyOthers(policyId,POLICY_NOTIFICATION);
+						} catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")");
+						}
+					}
+				}
+				if(groupId >= 0){
+					//we don't want commit to fail just because this does
+					if(newGroupId != null){
+					try{
+						notifyOthers(groupId,GROUP_NOTIFICATION,newGroupId);
+					} catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")",e);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")");
+					}
+					} else {
+					try{
+						notifyOthers(groupId,GROUP_NOTIFICATION);
+					} catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")",e);	
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")");
+					}
+					}
+				}
+				if(pdpId >= 0){
+					//we don't want commit to fail just because this does
+					try{
+						notifyOthers(pdpId,PDP_NOTIFICATION);
+					} catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")",e);
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")");
+					}
+				}
+			}
+			if(transactionTimer instanceof Thread){
+				transactionTimer.interrupt();
+			}
+		}
+		
+		@Override
+		public void rollbackTransaction() {
+			logger.debug("rollbackTransaction() as rollbackTransaction() called");
+			synchronized(emLock){
+				if(isTransactionOpen()){	
+
+					try{
+					em.getTransaction().rollback();					
+					} catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Could not rollback transaction");
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not rollback transaction");
+					}
+					try{
+						em.close();
+					}catch(Exception e){
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Could not close EntityManager");
+						PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not close EntityManager");
+					}
+
+				} else {
+					try{
+						em.close();
+					}catch(Exception e){
+						logger.warn("Could not close already closed transaction");
+					}
+				}
+
+			}
+			if(transactionTimer instanceof Thread){
+				transactionTimer.interrupt();
+			}
+
+
+		}
+
+		private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) {
+			logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) as createPolicy("+policy+", "+username+", "+policyScope+", "+policyName+", "+policyDataString+") called");
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			//em.getTransaction().begin();
+			//FIXME if the policy is already found but deleted, when we update it should we reset the created by and version number?
+			Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName");			
+			createPolicyQuery.setParameter("scope", policyScope);
+			createPolicyQuery.setParameter("policyName", policyName);
+			//createPolicyQuery.setParameter("deleted", false);
+			List<?> createPolicyQueryList = createPolicyQuery.getResultList();
+			PolicyEntity newPolicyEntity;
+			boolean update;
+			if(createPolicyQueryList.size() < 1){
+				newPolicyEntity = new PolicyEntity();
+				update = false;
+			} else if(createPolicyQueryList.size() > 1){
+				//something went wrong
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+				PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+				throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+			} else {
+				newPolicyEntity = (PolicyEntity)createPolicyQueryList.get(0);
+				update = true;
+			}			
+			
+			ActionBodyEntity newActionBodyEntity = null;
+			if(policy.getPolicyType().equals("Action")){
+				boolean abupdate = false;
+				if(newPolicyEntity.getActionBodyEntity() == null){
+					newActionBodyEntity = new ActionBodyEntity();
+				}else{
+					newActionBodyEntity = em.find(ActionBodyEntity.class, newPolicyEntity.getActionBodyEntity().getActionBodyId());
+					abupdate = true;
+				}
+
+				if(newActionBodyEntity != null){
+					if(!abupdate){
+						em.persist(newActionBodyEntity);
+					}
+					//build the file path
+					//trim the .xml off the end
+					String policyNameClean = FilenameUtils.removeExtension(policyName);
+					String actionBodyName = policyScope + "." + policyNameClean + ".json";
+					Path actionBodyPath = Paths.get(Webapps.getActionHome(), actionBodyName);
+					if(logger.isDebugEnabled()){
+						logger.debug("\nPolicyDBDao.createPolicy"
+								+ "\n   actionBodyPath = " + actionBodyPath);
+					}
+					//get the action body
+					String actionBodyString = null;
+					String actionBodyPathStr = null;
+					InputStream fileContentStream = null;
+
+					if (Files.exists(actionBodyPath)) {
+						try {
+							actionBodyPathStr = (actionBodyPath != null ? actionBodyPath.toString() : null);
+							fileContentStream = new FileInputStream(actionBodyPathStr);
+							actionBodyString = IOUtils.toString(fileContentStream);
+							if(logger.isDebugEnabled()){
+								logger.debug("\nPolicyDBDao.createPolicy"
+										+ "\n   actionBodyPathStr = " + actionBodyPathStr
+										+ "\n   actionBodyString = " + actionBodyString);
+							}
+						} catch (FileNotFoundException e) {
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")");
+							throw new IllegalArgumentException("The actionBodyPathStr file path " + actionBodyPathStr + " does not exist" 
+									+ "\nEXCEPTION: " + e);
+						} catch(IOException e2){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")",e2);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")");
+							throw new IllegalArgumentException("The actionBodyPath file path cannot be read" + fileContentStream 
+									+ "\nEXCEPTION: " + e2);
+						} finally {
+							IOUtils.closeQuietly(fileContentStream);
+						}
+						
+						if(actionBodyString == null){
+							throw new IllegalArgumentException("The file path (" + actionBodyPathStr + ") cannot be read");
+						}
+					
+					} else {
+						actionBodyString = "{}";
+					}
+
+					newActionBodyEntity.setActionBody(actionBodyString);
+					newActionBodyEntity.setActionBodyName(actionBodyName);
+					newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()");
+					newActionBodyEntity.setDeleted(false);
+					if(!abupdate){
+						newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()");
+					}
+					if(logger.isDebugEnabled()){
+						logger.debug("\nPolicyDBDao.createPolicy"
+								+ "\n   newActionBodyEntity.getActionBody() = " + newActionBodyEntity.getActionBody()
+								+ "\n   newActionBodyEntity.getActionBodyName() = " + newActionBodyEntity.getActionBodyName()
+								+ "\n   newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy()
+								+ "\n   newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy()
+								+ "\n   newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted()
+								+ "\n   FLUSHING to DB");
+					}
+					//push the actionBodyEntity to the DB
+					em.flush();
+				}else{
+					//newActionBodyEntity == null
+					//We have a actionBody in the policy but we found no actionBody in the DB
+					String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an "
+							+ "actionBody, but it could not be found in the DB for update."
+							+ "\n  policyScope = " + policyScope
+							+ "\n  policyName = " + policyName + "\n\n";
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(msg);
+					PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it could not be found in the DB for update: policyName = " + policyName);
+					throw new IllegalArgumentException(msg);
+				}
+			}
+
+			ConfigurationDataEntity newConfigurationDataEntity;
+			if(policy.getPolicyType().equals("Config")){
+				boolean configUpdate;
+				if(newPolicyEntity.getConfigurationData() == null){
+					newConfigurationDataEntity = new ConfigurationDataEntity();
+					configUpdate = false;
+				} else {
+					newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, newPolicyEntity.getConfigurationData().getConfigurationDataId());
+					configUpdate = true;
+				}
+
+				if(newConfigurationDataEntity != null){
+					if(!configUpdate){
+						em.persist(newConfigurationDataEntity);
+					}
+					//ConfigPolicy configPolicy = (ConfigPolicy)policy;
+					if(!stringEquals(newConfigurationDataEntity.getConfigurationName(),getConfigFile(policyName,policyScope,policy))){
+						newConfigurationDataEntity.setConfigurationName(getConfigFile(policyName,policyScope,policy));
+					}
+					if(newConfigurationDataEntity.getConfigType() == null || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())){
+						newConfigurationDataEntity.setConfigType(policy.getConfigType());
+					}
+					if(!configUpdate){
+						newConfigurationDataEntity.setCreatedBy(username);
+					}
+					if(newConfigurationDataEntity.getModifiedBy() == null || !newConfigurationDataEntity.getModifiedBy().equals(username)){
+						newConfigurationDataEntity.setModifiedBy(username);
+					}					
+					if(newConfigurationDataEntity.getDescription() == null || !newConfigurationDataEntity.getDescription().equals("")){
+						newConfigurationDataEntity.setDescription("");
+					}
+					if(newConfigurationDataEntity.getConfigBody() == null || newConfigurationDataEntity.getConfigBody().isEmpty() ||
+							(!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))){
+						//hopefully one of these won't be null
+						if(policy.getConfigBodyData() == null){
+							newConfigurationDataEntity.setConfigBody(policy.getJsonBody());
+						}else{
+							newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData());
+						}
+					}
+					if(newConfigurationDataEntity.isDeleted() == true){
+						newConfigurationDataEntity.setDeleted(false);
+					}
+
+					em.flush();
+				}else{//newConfigurationDataEntity == null
+					//We have a configurationData body in the policy but we found no configurationData body
+					//in the DB
+					String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a "
+							+ "configurationData body, but it could not be found in the DB for update."
+							+ "\n  policyScope = " + policyScope
+							+ "\n  policyName = " + policyName + "\n\n";
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(msg);
+					PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, but it could not be found in the DB for update: policyName = " + policyName);
+					throw new IllegalArgumentException(msg);
+				}
+
+			} else {
+				newConfigurationDataEntity = null;
+			}
+			if(!update){
+				em.persist(newPolicyEntity);
+			}
+			
+			policyId = newPolicyEntity.getPolicyId();
+			//policy version is now part of policy name
+			/*
+			if(update){
+				try{
+					String versionString = evaluateXPath("Policy/@Version", policyDataString);
+					int versionNum = Integer.parseInt(versionString);
+					if(versionNum < 1){
+						throw new NumberFormatException();
+					}
+					newPolicyEntity.setPolicyVersion(versionNum);
+				} catch(Exception e){
+					if(newPolicyEntity.isDeleted()){
+						newPolicyEntity.resetPolicyVersion();
+					} else {
+						newPolicyEntity.advancePolicyVersion();
+					}
+				}
+				
+
+			}
+			*/
+			if(!stringEquals(newPolicyEntity.getPolicyName(),policyName)){
+				newPolicyEntity.setPolicyName(policyName);
+			}
+			if(!stringEquals(newPolicyEntity.getCreatedBy(),username)){
+				newPolicyEntity.setCreatedBy(username);
+			}
+			if(!stringEquals(newPolicyEntity.getDescription(),policy.getPolicyDescription())){
+				newPolicyEntity.setDescription(policy.getPolicyDescription());
+			}
+			if(!stringEquals(newPolicyEntity.getModifiedBy(),username)){
+				newPolicyEntity.setModifiedBy(username);
+			}
+			if(!stringEquals(newPolicyEntity.getPolicyData(),policyDataString)){
+				newPolicyEntity.setPolicyData(policyDataString);
+			}
+			if(!stringEquals(newPolicyEntity.getScope(),policyScope)){
+				newPolicyEntity.setScope(policyScope);
+			}
+			if(newPolicyEntity.isDeleted() == true){
+				newPolicyEntity.setDeleted(false);
+			}
+			newPolicyEntity.setConfigurationData(newConfigurationDataEntity);
+			newPolicyEntity.setActionBodyEntity(newActionBodyEntity);
+			
+			
+				em.flush();
+				this.policyId = newPolicyEntity.getPolicyId();
+			}
+			
+			return;
+		}
+
+		@SuppressWarnings("unused")
+		public PolicyEntity getPolicy(int policyID){
+			return getPolicy(policyID,null,null);
+		}
+		public PolicyEntity getPolicy(String policyName,String scope){
+			return getPolicy(-1,policyName,scope);
+		}
+		private PolicyEntity getPolicy(int policyID, String policyName,String scope){
+			logger.debug("getPolicy(int policyId, String policyName) as getPolicy("+policyID+","+policyName+") called");
+			if(policyID < 0 && isNullOrEmpty(policyName,scope)){
+				throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank");
+			}
+
+			synchronized(emLock){
+				checkBeforeOperationRun(true);
+			//check if group exists
+				String policyId;
+				Query policyQuery;
+				if(!isNullOrEmpty(policyName,scope)){
+					policyId = policyName;
+					policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope");
+					policyQuery.setParameter("name", policyId);
+					policyQuery.setParameter("scope", scope);
+				} else{
+					policyId = String.valueOf(policyID);
+					policyQuery = em.createNamedQuery("PolicyEntity.FindById");
+					policyQuery.setParameter("id", policyId);
+				}
+			List<?> policyQueryList;
+			try{
+				policyQueryList = policyQuery.getResultList();
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to get policy with policyQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get policy with policyQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get policy "+policyId);
+			}
+			if(policyQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy does not exist with id "+policyId);
+				PolicyLogger.error("Policy does not exist with id "+policyId);
+				throw new PersistenceException("Group policy is being added to does not exist with id "+policyId);
+			} else if(policyQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one policy with the id "+policyId+" were found in the database");
+				PolicyLogger.error("Somehow, more than one policy with the id "+policyId+" were found in the database");
+				throw new PersistenceException("Somehow, more than one policy with the id "+policyId+" were found in the database");
+			}
+				return (PolicyEntity)policyQueryList.get(0);
+			}
+		}
+		
+		@Override
+		public void renamePolicy(String oldPath, String newPath,String username){
+			String[] oldPolicy = getScopeAndNameAndType(oldPath);
+			String[] newPolicy = getScopeAndNameAndType(newPath);
+			if(oldPolicy == null || newPolicy == null){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
+						//+oldPath+", "+newPath);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
+						+oldPath+", "+newPath);
+				throw new IllegalArgumentException("Could not parse one or more of the path names");
+			}
+			synchronized (emLock) {
+				checkBeforeOperationRun();
+				
+				PolicyEntity existingPolicy;
+				boolean existingPolicyDeleted = false;
+				List<?> groups = null;
+				try{
+					existingPolicy = getPolicy(newPolicy[1],newPolicy[0]);
+				} catch(Exception e){
+					existingPolicy = null;
+				}
+				if(existingPolicy != null && !existingPolicy.isDeleted()){
+					logger.error("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
+					throw new IllegalArgumentException("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
+				} else if(existingPolicy != null && existingPolicy.isDeleted()){
+					try{
+					Query getGroups = em.createQuery("SELECT g FROM GroupEntity g JOIN g.policies p WHERE p.policyId=:pid");
+
+					getGroups.setParameter("pid", existingPolicy.getPolicyId());
+					groups = getGroups.getResultList();
+					}catch(Exception e){
+						groups = new LinkedList<GroupEntity>();
+					}
+					for(Object o : groups){
+						
+						GroupEntity group = (GroupEntity)o;
+						group.removePolicyFromGroup(existingPolicy);
+					}
+					try{
+						em.flush();
+					}catch(Exception e){
+						logger.error("Error while removing the policy from groups: "+existingPolicy.getPolicyName());
+					}
+					try{
+					em.remove(existingPolicy);
+					em.flush();
+					}catch(Exception e){
+						logger.error("Could not remove the existing deleted policy: "+existingPolicy.getPolicyName());
+					}
+					existingPolicyDeleted = true;
+					//create the new policy
+					//for each of the groups, add the new policy
+				}
+				
+			PolicyEntity policyToRename;
+			try{
+			policyToRename = getPolicy(oldPolicy[1],oldPolicy[0]);
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not get policy record to rename: "
+					//+oldPolicy[1],e);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to rename: "
+					+oldPolicy[1]);
+				throw new PersistenceException("Could not get policy record to rename");
+			}
+			String policyDataString = null;
+			InputStream fileContentStream = null;
+			String policyFilePath = Paths.get(oldPath).toAbsolutePath().toString();
+			//I want to try the old path first, then if it doesn't work, try the new path
+			for(int i=0;i<2;i++){
+			try {
+				fileContentStream = new FileInputStream(policyFilePath);
+				policyDataString = IOUtils.toString(fileContentStream);
+			} catch (FileNotFoundException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught FileNotFoundException on new FileInputStream("+policyFilePath+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+policyFilePath+")");
+				//if we can't find the oldPath, we'll try the new path
+				if(i == 0){
+					policyFilePath = Paths.get(newPath).toAbsolutePath().toString();
+					continue;
+				}
+				throw new IllegalArgumentException("The file path does not exist");
+			} catch(IOException e2){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught IOException on newIOUtils.toString("+fileContentStream+")",e2);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")");
+				throw new IllegalArgumentException("The file path cannot be read");
+			} finally {
+				IOUtils.closeQuietly(fileContentStream);
+			}
+			if(policyDataString == null){
+				throw new IllegalArgumentException("The file path cannot be read");
+			}
+			//escape the loop
+			i=2;
+			}
+			policyToRename.setPolicyName(newPolicy[1]);
+			policyToRename.setPolicyData(policyDataString);
+			policyToRename.setScope(newPolicy[0]);
+			policyToRename.setModifiedBy(username);
+			if(policyToRename.getConfigurationData() != null){
+				//String configType = getPolicySubType(policyToRename.getConfigurationData().getConfigurationName());
+				String configType = policyToRename.getConfigurationData().getConfigType();
+				policyToRename.getConfigurationData().setConfigurationName(getConfigFile(newPolicy[1], newPolicy[0], configType));
+				policyToRename.getConfigurationData().setModifiedBy(username);
+			}
+			if(policyToRename.getActionBodyEntity() != null){
+				String newActionName = newPolicy[0]+"."+removeFileExtension(newPolicy[1])+".json";
+				policyToRename.getActionBodyEntity().setActionBodyName(newActionName);
+				policyToRename.getActionBodyEntity().setModifiedBy(username);
+			}
+			if(existingPolicyDeleted){
+				for(Object o : groups){
+					
+					GroupEntity group = (GroupEntity)o;
+					group.addPolicyToGroup(policyToRename);
+				}
+			}
+			em.flush();
+			this.policyId = policyToRename.getPolicyId();
+			this.newGroupId = oldPath;
+			}
+		}
+		
+		@Override
+		public GroupEntity getGroup(long groupKey){
+			logger.debug("getGroup(int groupKey) as getGroup("+groupKey+") called");
+			if(groupKey < 0){
+				throw new IllegalArgumentException("groupKey must be at least 0");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun(true);
+			//check if group exists
+			Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey");
+			groupQuery.setParameter("groupKey", groupKey);			
+			List<?> groupQueryList;
+			try{
+				groupQueryList = groupQuery.getResultList();
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to get group with groupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get group "+groupKey);
+			}
+			if(groupQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Group does not exist with groupKey "+groupKey);
+				PolicyLogger.error("Group does not exist with groupKey "+groupKey);
+				throw new PersistenceException("Group does not exist with groupKey "+groupKey);
+			} else if(groupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
+				PolicyLogger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
+				throw new PersistenceException("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
+			}
+				return (GroupEntity)groupQueryList.get(0);
+			}
+		}
+		
+		@Override
+		public GroupEntity getGroup(String groupId){
+			logger.debug("getGroup(String groupId) as getGroup("+groupId+") called");
+			if(isNullOrEmpty(groupId)){
+				throw new IllegalArgumentException("groupId must not be null or empty");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun(true);
+			//check if group exists
+			Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId");
+			groupQuery.setParameter("groupId", groupId);			
+			List<?> groupQueryList;
+			try{
+				groupQueryList = groupQuery.getResultList();
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to get group with groupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get group "+groupId);
+			}
+			if(groupQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Group does not exist with id "+groupId);
+				PolicyLogger.error("Group does not exist with id "+groupId);
+				throw new PersistenceException("Group does not exist with id "+groupId);
+			} else if(groupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the id "+groupId+" were found in the database");
+				PolicyLogger.error("Somehow, more than one group with the id "+groupId+" were found in the database");
+				throw new PersistenceException("Somehow, more than one group with the id "+groupId+" were found in the database");
+			}
+				return (GroupEntity)groupQueryList.get(0);
+			}
+		}
+		@Override
+		public List<?> getPdpsInGroup(long groupKey){
+			logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup("+groupKey+") called");
+			if(groupKey < 0){
+				throw new IllegalArgumentException("groupId must not be < 0");
+			}			
+			synchronized(emLock){
+				checkBeforeOperationRun(true);
+				Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group");
+				pdpsQuery.setParameter("group", getGroup(groupKey));
+				return pdpsQuery.getResultList();
+			}
+		}
+		@Override
+		public PdpEntity getPdp(long pdpKey){
+			logger.debug("getPdp(int pdpKey) as getPdp("+pdpKey+") called");
+			if(pdpKey < 0){
+				throw new IllegalArgumentException("pdpKey must be at least 0");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun(true);
+			//check if group exists
+			Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey");
+			pdpQuery.setParameter("pdpKey", pdpKey);			
+			List<?> pdpQueryList;
+			try{
+				pdpQueryList = pdpQuery.getResultList();
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to get pdp with pdpQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp with pdpQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get pdp "+pdpKey);
+			}
+			if(pdpQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Pdp does not exist with pdpKey "+pdpKey);
+				PolicyLogger.error("Pdp does not exist with pdpKey "+pdpKey);
+				throw new PersistenceException("Pdp does not exist with pdpKey "+pdpKey);
+			} else if(pdpQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
+				PolicyLogger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
+				throw new PersistenceException("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
+			}
+				return (PdpEntity)pdpQueryList.get(0);
+			}
+		}
+		
+		//FIXME: maybe this should be boolean
+		public void deletePolicy(String policyToDeletes){
+			synchronized(emLock){
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}
+				checkBeforeOperationRun();
+			logger.debug("deletePolicy(String policyToDeletes) as deletePolicy("+policyToDeletes+") called");
+			String[] scopeNameAndType = getScopeAndNameAndType(policyToDeletes);
+			if(scopeNameAndType == null){
+				throw new IllegalArgumentException("Could not parse file path");
+			}
+			String realScope = scopeNameAndType[0];
+			String realName = scopeNameAndType[1];
+//				if(isTransactionOpen()){
+//					throw new IllegalStateException("A transaction is already open which has not been committed");
+//				}
+				Query deletePolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName AND p.deleted=:deleted");			
+				deletePolicyQuery.setParameter("scope",realScope);
+				deletePolicyQuery.setParameter("policyName", realName);
+				deletePolicyQuery.setParameter("deleted", false);
+				List<?> deletePolicyQueryList = deletePolicyQuery.getResultList();
+				if(deletePolicyQueryList.size() < 1){
+					logger.warn("The policy being deleted could not be found.");
+					return;
+				} else if(deletePolicyQueryList.size() > 1){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+					PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+					throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
+				} else {
+					//em.getTransaction().begin();
+					PolicyEntity policyToDelete = (PolicyEntity)deletePolicyQueryList.get(0);
+					policyToDelete.setDeleted(true);
+					if(policyToDelete.getConfigurationData() != null){
+						ConfigurationDataEntity cde = em.find(ConfigurationDataEntity.class,policyToDelete.getConfigurationData().getConfigurationDataId());					
+						if(cde != null){
+							cde.setDeleted(true);
+						}
+					}
+					if(policyToDelete.getActionBodyEntity() != null){
+						ActionBodyEntity abe = em.find(ActionBodyEntity.class,policyToDelete.getActionBodyEntity().getActionBodyId());					
+						if(abe != null){
+							abe.setDeleted(true);
+						}
+					}
+					
+					em.flush();
+					this.policyId = policyToDelete.getPolicyId();
+		
+				}
+			}
+
+		}
+		
+
+		@Override
+		public boolean isTransactionOpen() {
+			logger.debug("isTransactionOpen() as isTransactionOpen() called");
+			synchronized(emLock){
+			return em.isOpen() && em.getTransaction().isActive();	
+			}
+		}
+
+
+		@Override
+		public void clonePolicy(String oldPolicyPath, String newPolicyPath, String username){
+			String[] oldPolicyData = getScopeAndNameAndType(oldPolicyPath);
+			String[] newPolicyData = getScopeAndNameAndType(newPolicyPath);
+			if(oldPolicyData == null || newPolicyData == null){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
+						//+oldPolicyPath+", "+newPolicyPath);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
+						+oldPolicyPath+", "+newPolicyPath);
+				throw new IllegalArgumentException("Could not parse the oldPolicyPath or newPolicyPath");
+			}
+			PolicyEntity oldPolicy;
+			try{
+				oldPolicy = getPolicy(oldPolicyData[1],oldPolicyData[0]);
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not get policy record to clone: "
+						//+oldPolicyData[1],e);
+				PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to clone: "
+						+oldPolicyData[1]);
+					throw new PersistenceException("Could not get policy record to clone");
+			}
+			ConfigurationDataEntity clonedConfig = null;
+			if(oldPolicy.getConfigurationData() != null){
+				clonedConfig = new ConfigurationDataEntity();
+				em.persist(clonedConfig);
+				clonedConfig.setConfigBody(oldPolicy.getConfigurationData().getConfigBody());
+				clonedConfig.setConfigType(oldPolicy.getConfigurationData().getConfigType());
+				clonedConfig.setCreatedBy(username);
+				clonedConfig.setConfigurationName(getConfigFile(newPolicyData[1], newPolicyData[0], oldPolicy.getConfigurationData().getConfigType()));
+				clonedConfig.setDescription(oldPolicy.getConfigurationData().getDescription());
+				clonedConfig.setModifiedBy(username);
+				em.flush();
+			}
+			ActionBodyEntity clonedAction = null;
+			if(oldPolicy.getActionBodyEntity() != null){
+				clonedAction = new ActionBodyEntity();
+				em.persist(clonedAction);
+				clonedAction.setActionBody(oldPolicy.getActionBodyEntity().getActionBody());
+				clonedAction.setActionBodyName(newPolicyData[0]+"."+newPolicyData[1]+".json");
+				clonedAction.setCreatedBy(username);
+				clonedAction.setModifiedBy(username);
+				em.flush();
+			}			
+			
+			
+		}
+		
+		@Override
+		public void createPolicy(String filePath, String username) {
+			logger.debug("createPolicy(String filePath, String username) as createPolicy("+filePath+","+username+") called");
+			//get just the scope and file name
+			//its actually scope, name, and type now
+			String[] scopeAndName = getScopeAndNameAndType(filePath);
+			if(scopeAndName == null){
+				throw new IllegalArgumentException("The file path could not be parsed");
+			}
+			PolicyRestAdapter policy = new PolicyRestAdapter();
+
+			policy.setPolicyType(scopeAndName[2]);
+			policy.setPolicyDescription("");
+
+			String policyName = scopeAndName[1];
+			try{
+				policyName = stripPolicyName(policyName);
+			}catch(IllegalArgumentException e){
+				if(scopeAndName[2].equals("Config")){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error(e.getMessage());
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception calling stripPolicyName with policy name: "+policyName);
+					throw new IllegalArgumentException(e.getMessage(),e);
+				} else {
+					logger.warn(e.getMessage());
+				}
+			}
+			policy.setPolicyName(policyName);
+			String policyDataString = null;
+			InputStream fileContentStream = null;
+			try {
+				fileContentStream = new FileInputStream(filePath);
+				policyDataString = IOUtils.toString(fileContentStream);
+			} catch (FileNotFoundException e) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught FileNotFoundException on new FileInputStream("+filePath+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+filePath+")");
+				throw new IllegalArgumentException("The file path does not exist");
+			} catch(IOException e2){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught IOException on newIOUtils.toString("+fileContentStream+")",e2);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")");
+				throw new IllegalArgumentException("The file path cannot be read");
+			} finally {
+				IOUtils.closeQuietly(fileContentStream);
+			}
+			if(policyDataString == null){
+				throw new IllegalArgumentException("The file path cannot be read");
+			}
+			try{
+			String policyDescription = getElementFromXMLString("/Description", policyDataString);
+			if(policyDescription != null){
+				policy.setPolicyDescription(policyDescription);
+			}
+			} catch(Exception e){
+				logger.warn("Could not get description from the policy file");
+			}
+			if(scopeAndName[2].equals("Config")){
+				//this method is not used for config, since there is no way to get config info (could be modified to)
+				String configPath;
+				try{
+				configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
+				if(configPath == null){
+					throw new NullPointerException("configPath is null");
+				}
+				} catch(Exception e){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Could not get config file path from policy file",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get config file path from policy file");
+					throw new IllegalArgumentException("Could not get config file path from policy file");
+				}
+				configPath = processConfigPath(configPath);
+				logger.debug("The location of our config file is: "+configPath);
+				policy.setConfigType(getPolicySubType(configPath));
+				logger.debug("Config type is: "+policy.getConfigType());
+
+				String configDataString = readConfigFile(configPath);
+				policy.setConfigBodyData(configDataString);
+			}
+			createPolicy(policy,username,scopeAndName[0],scopeAndName[1],policyDataString);			
+		}
+		private String processConfigPath(String configPath){
+			String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS);
+			if(webappsPath == null){
+				logger.error("Webapps property does not exist");
+				throw new IllegalArgumentException("Webapps property does not exist");
+			}
+			configPath = configPath.replace("$URL", webappsPath);
+			//make sure the correct slashes are in
+			try{
+			configPath = Paths.get(configPath).toString();
+			} catch(InvalidPathException e){
+				logger.error("Invalid config path: "+configPath);
+				throw new IllegalArgumentException("Invalid config path: "+configPath);
+			}
+			return configPath;
+		}
+		private String readConfigFile(String configPath){
+			String configDataString = null;
+			InputStream configContentStream = null;
+			try {
+				configContentStream = new FileInputStream(configPath);
+				configDataString = IOUtils.toString(configContentStream);
+			} catch (FileNotFoundException e) {
+				logger.error("Caught FileNotFoundException on new FileInputStream("+configPath+")",e);
+				throw new IllegalArgumentException("The config file path does not exist");
+			} catch(IOException e2){
+				logger.error("Caught IOException on newIOUtils.toString("+configContentStream+")",e2);
+				throw new IllegalArgumentException("The config file path cannot be read");
+			} finally {
+				IOUtils.closeQuietly(configContentStream);
+			}
+			if(configDataString == null){
+				throw new IllegalArgumentException("The config file path cannot be read");
+			}
+			return configDataString;
+		}
+		
+		@Override
+		public void createPolicy(Policy policy, String username){
+			logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy("+policy+","+username+") called");
+			String policyScope = computeScope(policy.policyAdapter.getParentPath(),policy.policyAdapter.getUserGitPath());
+			
+			//Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
+			//and this transaction is intercepted up stream.
+			InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType)policy.getCorrectPolicyDataObject());
+			String policyDataString;
+			try {
+				policyDataString = IOUtils.toString(policyXmlStream);
+			} catch (IOException e) {
+				policyDataString = "could not read";
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught IOException on IOUtils.toString("+policyXmlStream+")",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught IOException on IOUtils.toString("+policyXmlStream+")");
+				throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter.");
+			}
+			IOUtils.closeQuietly(policyXmlStream);
+			String configPath = "";
+			if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
+				configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
+			} else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
+				configPath = evaluateXPath("/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " +policy.policyAdapter.getActionAttribute()+ ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", policyDataString);
+			}
+			
+			String prefix = null;
+			if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
+				
+				prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName()));
+				if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){
+					String configData = "";
+					try{
+						String newConfigPath = configPath;
+						try{
+							newConfigPath = processConfigPath(newConfigPath);							
+						}catch(Exception e2){
+							logger.error("Could not process config path: "+newConfigPath,e2);
+						}
+						configData = readConfigFile(newConfigPath);
+					}catch(Exception e){
+						logger.error("Could not read config body data for "+configPath,e);
+					}
+					policy.policyAdapter.setConfigBodyData(configData);
+				}
+				
+			} else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
+				
+				prefix = "Action_";
+				
+			} else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Decision")) {
+				
+				prefix = "Decision_";
+			}
+			
+			if(!(policy.policyAdapter.getData() instanceof PolicyType)){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The data field is not an instance of PolicyType");
+				PolicyLogger.error("The data field is not an instance of PolicyType");
+				throw new IllegalArgumentException("The data field is not an instance of PolicyType");
+			}
+			String finalName = prefix+policy.policyAdapter.getPolicyName()+"."+((PolicyType)policy.policyAdapter.getData()).getVersion()+".xml";
+			if(policy.policyAdapter.getConfigType() == null || policy.policyAdapter.getConfigType().equals("")){
+				//we need to make it
+				//get the config file extension
+				String ext = "";
+				if (configPath != null) {
+					if (!configPath.equalsIgnoreCase("")) {
+						ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());;
+					}
+				}
+				
+				if(ext.contains("txt")){
+					policy.policyAdapter.setConfigType(OTHER_CONFIG);
+				} else if(ext.contains("json")){
+					policy.policyAdapter.setConfigType(JSON_CONFIG);
+				} else if(ext.contains("xml")){
+					policy.policyAdapter.setConfigType(XML_CONFIG);
+				} else if(ext.contains("properties")){
+					policy.policyAdapter.setConfigType(PROPERTIES_CONFIG);
+				} else {
+					if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")){
+						policy.policyAdapter.setConfigType(JSON_CONFIG);
+					}
+				}
+			}
+			createPolicy(policy.policyAdapter, username, policyScope,finalName,policyDataString);
+			
+		}
+		
+		@Override
+		public void close(){
+			synchronized(emLock){
+				if(em.isOpen()){
+					if(em.getTransaction().isActive()){
+						em.getTransaction().rollback();
+					}
+					em.close();
+				}
+				if(transactionTimer instanceof Thread){
+					transactionTimer.interrupt();
+				}
+			}
+		}
+
+
+
+		@Override
+		public void createGroup(String groupId, String groupName, String groupDescription, String username) {
+			logger.debug("deletePolicy(String policyToDeletes) as createGroup("+groupId+", "+groupName+", "+groupDescription+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}			
+			//parameter check
+			if(isNullOrEmpty(groupId, groupName, username)){
+				throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty");
+			}
+			if(!(groupDescription instanceof String)){
+				groupDescription = "";
+			}
+
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			checkGroupQuery.setParameter("groupId", groupId);
+			checkGroupQuery.setParameter("deleted", false);
+			List<?> checkGroupQueryList;
+			try{
+				checkGroupQueryList = checkGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on checkGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check for existing group");
+			}
+			if(checkGroupQueryList.size() > 0){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The group being added already exists with id "+groupId);
+				PolicyLogger.error("The group being added already exists with id "+groupId);
+				throw new PersistenceException("The group being added already exists with id "+groupId);
+			}
+			//em.getTransaction().begin();
+			GroupEntity newGroup = new GroupEntity();
+			em.persist(newGroup);
+			newGroup.setCreatedBy(username);
+			newGroup.setModifiedBy(username);
+			newGroup.setGroupName(groupName);
+			newGroup.setGroupId(groupId);
+			newGroup.setDescription(groupDescription);
+			
+			em.flush();
+			this.groupId = newGroup.getGroupKey();
+			}
+		}
+
+		@Override
+		public void updateGroup(EcompPDPGroup group, String username){
+			logger.debug("updateGroup(PDPGroup group) as updateGroup("+group+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}			
+			
+			//parameter check
+			if(group == null){
+				throw new IllegalArgumentException("PDPGroup group must not be null");
+			}
+			if(isNullOrEmpty(group.getId(), username)){
+				throw new IllegalArgumentException("group.getId() and username must not be null or empty");
+			}
+
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			getGroupQuery.setParameter("groupId", group.getId());
+			getGroupQuery.setParameter("deleted", false);
+			List<?> getGroupQueryList;
+			try{
+				getGroupQueryList = getGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on getGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get group "+group.getId()+" for editing");
+			}
+			if(getGroupQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The group cannot be found to update with id "+group.getId());
+				PolicyLogger.error("The group cannot be found to update with id "+group.getId());
+				throw new PersistenceException("The group cannot be found to update with id "+group.getId());
+			} else if(getGroupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+				PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+				throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+			}
+			//em.getTransaction().begin();
+			GroupEntity groupToUpdate = (GroupEntity)getGroupQueryList.get(0);
+			if(!stringEquals(groupToUpdate.getModifiedBy(), username)){
+				groupToUpdate.setModifiedBy(username);
+			}
+			if(group.getDescription() != null && !stringEquals(group.getDescription(),groupToUpdate.getDescription())){
+				groupToUpdate.setDescription(group.getDescription());
+			}
+			//let's find out what policies have been deleted
+			StdPDPGroup oldGroup = null;
+			try {
+				oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId());
+			} catch (PAPException e1) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("We cannot get the group from the papEngine to delete policies",e1);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "We cannot get the group from the papEngine to delete policies");
+			}
+			if(oldGroup == null){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("We cannot get the group from the papEngine to delete policies");
+				PolicyLogger.error("We cannot get the group from the papEngine to delete policies");
+			} else {
+
+				Set<String> newPolicySet = new HashSet<String>(group.getPolicies().size());
+				//a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison
+				for(PDPPolicy pol: group.getPolicies()){
+					newPolicySet.add(pol.getId());
+				}
+				for(PDPPolicy pol : oldGroup.getPolicies()){
+					//should be fast since getPolicies uses a HashSet in StdPDPGroup
+					if(!newPolicySet.contains(pol.getId())){
+						String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId());
+						PolicyEntity policyToDelete;
+						try{
+						policyToDelete = getPolicy(scopeAndName[0],scopeAndName[1]);
+						}catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Could not get policy to remove: "+pol.getId(),e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get policy to remove: "+pol.getId());
+							throw new PersistenceException("Could not get policy to remove: "+pol.getId());
+						}
+						groupToUpdate.getPolicies().remove(policyToDelete);
+
+					}
+				}
+			}
+			if(group.getName() != null && !stringEquals(group.getName(),groupToUpdate.getgroupName())){
+				//we need to check if the new id exists in the database
+				String newGroupId = createNewPDPGroupId(group.getName());
+				Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+				checkGroupQuery.setParameter("groupId", newGroupId);
+				checkGroupQuery.setParameter("deleted", false);
+				List<?> checkGroupQueryList;
+				try{
+					checkGroupQueryList = checkGroupQuery.getResultList();
+				} catch(Exception e){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught Exception on checkGroupQuery.getResultList()",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
+					throw new PersistenceException("Query failed trying to check for existing group");
+				}
+				if(checkGroupQueryList.size() != 0){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("The new group name already exists, group id "+newGroupId);
+					PolicyLogger.error("The new group name already exists, group id "+newGroupId);
+					throw new PersistenceException("The new group name already exists, group id "+newGroupId);
+				}
+				groupToUpdate.setGroupId(newGroupId);
+				groupToUpdate.setGroupName(group.getName());
+				this.newGroupId = group.getId();
+			}
+			
+			em.flush();
+			this.groupId = groupToUpdate.getGroupKey();
+			}
+		}
+
+		@Override
+		public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) {
+			logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup("+pdpID+", "+groupID+", "+pdpName+", "+pdpDescription+", "+pdpJmxPort+", "+username+") called");
+			if(isNullOrEmpty(pdpID, groupID,pdpName,username)){
+				throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty");
+			}
+			if(!(pdpDescription instanceof String)){
+				pdpDescription = "";
+			}
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}	
+
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			checkGroupQuery.setParameter("groupId", groupID);
+			checkGroupQuery.setParameter("deleted", false);
+			List<?> checkGroupQueryList;
+			try{
+				checkGroupQueryList = checkGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to check for existing group on checkGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check for existing group");
+			}
+			if(checkGroupQueryList.size() != 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The group does not exist");
+				PolicyLogger.error("The group does not exist");
+				throw new PersistenceException("The group does not exist");
+			}
+			Query checkDuplicateQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
+			checkDuplicateQuery.setParameter("pdpId", pdpID);
+			checkDuplicateQuery.setParameter("deleted", false);
+			List<?> checkDuplicateList;
+			try{
+				checkDuplicateList = checkDuplicateQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check for duplicate PDP "+pdpID);
+			}
+			PdpEntity newPdp;
+			if(checkDuplicateList.size() > 0){
+				logger.warn("PDP already exists with id "+pdpID);				
+				newPdp = (PdpEntity)checkDuplicateList.get(0);
+			} else {
+				newPdp = new PdpEntity();
+		em.persist(newPdp);
+			}			
+
+			newPdp.setCreatedBy(username);
+			newPdp.setDeleted(false);
+			newPdp.setDescription(pdpDescription);
+			newPdp.setGroup((GroupEntity)checkGroupQueryList.get(0));
+			newPdp.setJmxPort(pdpJmxPort);
+			newPdp.setModifiedBy(username);
+			newPdp.setPdpId(pdpID);
+			newPdp.setPdpName(pdpName);
+			
+			em.flush();
+			this.pdpId = newPdp.getPdpKey();
+
+			}
+		}
+
+		
+		@Override
+		public void updatePdp(EcompPDP pdp, String username){
+			logger.debug("updatePdp(PDP pdp, String username) as updatePdp("+pdp+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}
+			//parameter check
+			if(pdp == null){
+				throw new IllegalArgumentException("PDP pdp must not be null");
+			}
+			if(isNullOrEmpty(pdp.getId(),username)){
+				throw new IllegalArgumentException("pdp.getId() and username must not be null or empty");
+			}
+
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
+			getPdpQuery.setParameter("pdpId", pdp.getId());
+			getPdpQuery.setParameter("deleted", false);
+			List<?> getPdpQueryList;
+			try{
+				getPdpQueryList = getPdpQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on getPdpQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get PDP "+pdp.getId());
+			}
+			if(getPdpQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The pdp cannot be found to update with id "+pdp.getId());
+				PolicyLogger.error("The pdp cannot be found to update with id "+pdp.getId());
+				throw new PersistenceException("The pdp cannot be found to update with id "+pdp.getId());
+			} else if(getPdpQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+				PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+				throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+			}
+			//em.getTransaction().begin();
+			PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
+			if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
+				pdpToUpdate.setModifiedBy(username);
+			}
+			if(pdp.getDescription() != null && !stringEquals(pdp.getDescription(),pdpToUpdate.getDescription())){
+				pdpToUpdate.setDescription(pdp.getDescription());
+			}
+			if(pdp.getName() != null && !stringEquals(pdp.getName(),pdpToUpdate.getPdpName())){
+				pdpToUpdate.setPdpName(pdp.getName());
+			}
+			if(pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())){
+				pdpToUpdate.setJmxPort(pdp.getJmxPort());
+			}
+			
+			em.flush();
+			this.pdpId = pdpToUpdate.getPdpKey();
+			}
+		}
+		
+		@Override
+		public void movePdp(EcompPDP pdp, EcompPDPGroup group, String username){
+			logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp("+pdp+","+group+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");
+//			}
+			if(pdp == null || group == null){
+				throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null");
+			}
+			if(isNullOrEmpty(username,pdp.getId(),group.getId())){
+				throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty");
+			}
+			
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			//check if pdp exists
+			Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
+			getPdpQuery.setParameter("pdpId", pdp.getId());
+			getPdpQuery.setParameter("deleted", false);
+			List<?> getPdpQueryList;
+			try{
+				getPdpQueryList = getPdpQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on getPdpQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get pdp to move with id "+pdp.getId());
+			}
+			if(getPdpQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The pdp cannot be found to move with id "+pdp.getId());
+				PolicyLogger.error("The pdp cannot be found to move with id "+pdp.getId());
+				throw new PersistenceException("The pdp cannot be found to move with id "+pdp.getId());
+			} else if(getPdpQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+				PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+				throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
+			}
+			
+			//check if new group exists
+			Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			checkGroupQuery.setParameter("groupId", group.getId());
+			checkGroupQuery.setParameter("deleted", false);
+			List<?> checkGroupQueryList;
+			try{
+				checkGroupQueryList = checkGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to get group on checkGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group on checkGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get new group "+group.getId());
+			}
+			if(checkGroupQueryList.size() != 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The group "+group.getId()+" does not exist");
+				PolicyLogger.error("The group "+group.getId()+" does not exist");
+				throw new PersistenceException("The group "+group.getId()+" does not exist");
+			}
+			GroupEntity groupToMoveInto = (GroupEntity)checkGroupQueryList.get(0);
+			//move it
+			//em.getTransaction().begin();
+			PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
+			pdpToUpdate.setGroup(groupToMoveInto);
+			if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
+				pdpToUpdate.setModifiedBy(username);
+			}
+			
+			em.flush();
+			this.pdpId = pdpToUpdate.getPdpKey();
+			}
+		}
+		
+		@Override
+		public void changeDefaultGroup(EcompPDPGroup group, String username){
+			logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup("+group+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");
+//			}
+			//parameter check
+			if(group == null){
+				throw new IllegalArgumentException("PDPGroup group must not be null");
+			}
+			if(isNullOrEmpty(group.getId(),username)){
+				throw new IllegalArgumentException("group.getId() and username must not be null or empty");
+			}
+			
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			getGroupQuery.setParameter("groupId", group.getId());
+			getGroupQuery.setParameter("deleted", false);
+			List<?> getGroupQueryList;
+			try{
+				getGroupQueryList = getGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on getGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to get group "+group.getId());
+			}
+			if(getGroupQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The group cannot be found to set default with id "+group.getId());
+				PolicyLogger.error("The group cannot be found to set default with id "+group.getId());				
+				throw new PersistenceException("The group cannot be found to set default with id "+group.getId());
+			} else if(getGroupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+				PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+				throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
+			}
+			//em.getTransaction().begin();
+			GroupEntity newDefaultGroup = (GroupEntity)getGroupQueryList.get(0);
+			newDefaultGroup.setDefaultGroup(true);
+			if(!stringEquals(newDefaultGroup.getModifiedBy(), username)){
+				newDefaultGroup.setModifiedBy(username);
+			}
+			
+			em.flush();
+			this.groupId = newDefaultGroup.getGroupKey();
+			Query setAllGroupsNotDefault = em.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g.groupKey<>:groupKey");
+			//not going to set modified by for all groups
+			setAllGroupsNotDefault.setParameter("defaultGroup", false);
+			setAllGroupsNotDefault.setParameter("deleted", false);
+			setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey());
+			try{
+				logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default");
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception on setAllGroupsNotDefault.executeUpdate()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on setAllGroupsNotDefault.executeUpdate()");
+				throw new PersistenceException("Could not set all other groups default to false");
+			}
+			
+			em.flush();
+			}
+		}
+
+
+		@Override
+		public void deleteGroup(EcompPDPGroup group, EcompPDPGroup moveToGroup, String username) throws PAPException {
+			logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}
+			if(group == null){
+				throw new IllegalArgumentException("PDPGroup group cannot be null");
+			}
+			if(isNullOrEmpty(username,group.getId())){
+				throw new IllegalArgumentException("group.getId() and and username must not be null or empty");
+			}
+
+			if(group.isDefaultGroup()){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be.");
+				PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be.");
+				throw new PAPException("You cannot delete the default group.");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			Query deleteGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			deleteGroupQuery.setParameter("groupId", group.getId());
+			deleteGroupQuery.setParameter("deleted", false);
+			List<?> deleteGroupQueryList;
+			try{
+				deleteGroupQueryList = deleteGroupQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to check if group exists deleteGroupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check if group exists");
+			}
+			if(deleteGroupQueryList.size() < 1){
+				logger.warn("The group could not be found with id " + group.getId());
+				return;
+			} else if(deleteGroupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
+				PolicyLogger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
+				throw new PersistenceException("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
+			}				
+				
+				Query pdpsInGroupQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted");
+				pdpsInGroupQuery.setParameter("group", ((GroupEntity)deleteGroupQueryList.get(0)));
+				pdpsInGroupQuery.setParameter("deleted", false);
+				List<?> pdpsInGroupList;
+				try{
+					pdpsInGroupList = pdpsInGroupQuery.getResultList();
+				} catch(Exception e){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()");
+					throw new PersistenceException("Query failed trying to get PDPs in group");
+				}
+				//em.getTransaction().begin();
+				if(pdpsInGroupList.size() > 0){
+					if(moveToGroup != null){
+						Query checkMoveToGroupQuery = em.createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted");
+						checkMoveToGroupQuery.setParameter("groupId", moveToGroup.getId());
+						checkMoveToGroupQuery.setParameter("deleted", false);
+						List<?> checkMoveToGroupList;
+						try{
+							checkMoveToGroupList = checkMoveToGroupQuery.getResultList();
+						} catch(Exception e){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()",e);
+							PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()");
+							throw new PersistenceException("Query failed trying to check if group exists");
+						}
+						if(checkMoveToGroupList.size() < 1){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("The group could not be found with id " + moveToGroup.getId());
+							PolicyLogger.error("The group could not be found with id " + moveToGroup.getId());
+							throw new PersistenceException("The group could not be found with id " + moveToGroup.getId());
+						} else if(checkMoveToGroupList.size() > 1){
+							//TODO:EELF Cleanup - Remove logger
+							//logger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
+							PolicyLogger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
+							throw new PersistenceException("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
+						} else {
+							GroupEntity newGroup = (GroupEntity)checkMoveToGroupList.get(0);
+							for(Object pdpObject : pdpsInGroupList){
+								PdpEntity pdp = (PdpEntity)pdpObject;
+								pdp.setGroup(newGroup);
+								if(!stringEquals(pdp.getModifiedBy(),username)){
+									pdp.setModifiedBy(username);
+								}
+								try{
+									
+								em.flush();
+								this.newGroupId = newGroup.getGroupId();
+								} catch(PersistenceException e){
+									//TODO:EELF Cleanup - Remove logger
+									//logger.error("Caught PersistenceException trying to set pdp group to null on em.flush()",e);
+									PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PersistenceException trying to set pdp group to null on em.flush()");
+									throw new PersistenceException("Query failed trying to set pdp group to ");
+								}
+							}
+						}
+					} else {
+						//TODO:EELF Cleanup - Remove logger
+						//logger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to");
+						PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to");
+						throw new PAPException("Group has PDPs. Must provide a group for them to move to");
+					}
+				} 
+				
+				//delete group here
+								
+				GroupEntity groupToDelete = (GroupEntity)deleteGroupQueryList.get(0);
+				groupToDelete.setDeleted(true);
+				if(!stringEquals(groupToDelete.getModifiedBy(), username)){
+					groupToDelete.setModifiedBy(username);
+				}
+				
+				//try{
+								
+				em.flush();
+				this.groupId = groupToDelete.getGroupKey();
+				//return;
+				//} catch(PersistenceException pe){
+					//logger.error("Database error while marking policy or config as deleted");					
+					//throw new PersistenceException("Database error while marking policy or config as deleted");
+				//}	
+			}
+			}
+
+		@Override
+		public void addPolicyToGroup(String groupID, String policyID, String username) {
+			logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}
+			if(isNullOrEmpty(groupID, policyID, username)){
+				throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun();
+			//check if group exists
+			Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
+			groupQuery.setParameter("groupId", groupID);
+			groupQuery.setParameter("deleted", false);
+			List<?> groupQueryList;
+			try{
+				groupQueryList = groupQuery.getResultList();
+			}catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to check if group exists groupQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check if group "+groupID+" exists");
+			}
+			if(groupQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Group policy is being added to does not exist with id "+groupID);
+				PolicyLogger.error("Group policy is being added to does not exist with id "+groupID);
+				throw new PersistenceException("Group policy is being added to does not exist with id "+groupID);
+			} else if(groupQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
+				PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
+				throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
+			}
+			//we need to convert the form of the policy id that is used groups into the form that is used 
+			//for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml)
+			String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID);			
+			Query policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p.deleted=:deleted");
+			policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]);
+			policyQuery.setParameter("scope", policyNameScopeAndVersion[1]);			
+			policyQuery.setParameter("deleted", false);
+			List<?> policyQueryList;
+			try{
+				policyQueryList = policyQuery.getResultList();
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Caught Exception trying to check if policy exists policyQuery.getResultList()",e);
+				PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if policy exists policyQuery.getResultList()");
+				throw new PersistenceException("Query failed trying to check if policy "+policyNameScopeAndVersion[0]+" exists");
+			}
+			if(policyQueryList.size() < 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
+				PolicyLogger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
+				throw new PersistenceException("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);				
+			} else if(policyQueryList.size() > 1){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
+				PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
+				throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
+			}
+			//em.getTransaction().begin();
+			GroupEntity group = (GroupEntity)groupQueryList.get(0);
+			PolicyEntity policy = (PolicyEntity)policyQueryList.get(0);
+			group.addPolicyToGroup(policy);
+			em.flush();
+			}
+		}
+
+		//this means delete pdp not just remove from group
+		@Override
+		public void removePdpFromGroup(String pdpID, String username) {
+			logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup("+pdpID+","+username+") called");
+//			if(isTransactionOpen()){
+//				logger.error("A transaction is already open which has not been committed");
+//				throw new IllegalStateException("A transaction is already open which has not been committed");				
+//			}
+			if(isNullOrEmpty(pdpID,username)){
+				throw new IllegalArgumentException("pdpID and username must not be null or empty");
+			}
+			synchronized(emLock){
+				checkBeforeOperationRun();
+				Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
+				pdpQuery.setParameter("pdpId", pdpID);
+				pdpQuery.setParameter("deleted", false);
+				List<?> pdpList;
+				try{
+					pdpList = pdpQuery.getResultList();
+				} catch(Exception e){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Caught Exception trying to check if pdp exists  pdpQuery.getResultList()",e);
+					PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if pdp exists  pdpQuery.getResultList()");
+					throw new PersistenceException("Query failed trying to check if pdp "+pdpID+" exists");
+				}
+				if(pdpList.size() > 1){
+					//TODO:EELF Cleanup - Remove logger
+					//logger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
+					PolicyLogger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
+					throw new PersistenceException("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
+				} else if(pdpList.size() < 1){
+					//logger.warn("Pdp being removed does not exist with id "+pdpID);
+					PolicyLogger.error("Pdp being removed does not exist with id "+pdpID);
+					return;
+				}
+				//em.getTransaction().begin();
+				PdpEntity pdp = (PdpEntity)pdpList.get(0);
+				pdp.setGroup(null);
+				if(!stringEquals(pdp.getModifiedBy(),username)){
+					pdp.setModifiedBy(username);
+				}
+				pdp.setDeleted(true);
+				
+				em.flush();
+				this.pdpId = pdp.getPdpKey();
+			}
+		}
+	}
+
+				
+	
+	private static String getDefaultWorkspace(){
+		return "admin";
+	}
+	
+	private PolicyDBDao(){
+		
+	}
+	public static PolicyDBDaoTestClass getPolicyDBDaoTestClass(){
+		return new PolicyDBDao().new PolicyDBDaoTestClass();
+	}
+	final class PolicyDBDaoTestClass {
+		String[] getScopeAndNameAndType(final String path){
+			return PolicyDBDao.getScopeAndNameAndType(path);
+		}
+		String getGitPath(){
+			return PolicyDBDao.getGitPath();
+		}
+		String getConfigFile(String filename, String scope, PolicyRestAdapter policy){
+			return PolicyDBDao.this.getConfigFile(filename, scope, policy);
+		}
+		String computeScope(String fullPath, String pathToExclude){
+			return PolicyDBDao.computeScope(fullPath, pathToExclude);
+		}
+		String encryptPassword(String password) throws Exception{
+			return PolicyDBDao.encryptPassword(password);
+		}
+		String decryptPassword(String password) throws Exception{
+			return PolicyDBDao.decryptPassword(password);
+		}
+		String getDescriptionFromXacml(String xacmlData){
+			return PolicyDBDao.getDescriptionFromXacml(xacmlData);
+		}
+		
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java
new file mode 100644
index 0000000..4e9ddb4
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.components;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.PersistenceException;
+
+import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter;
+import org.openecomp.policy.rest.jpa.GroupEntity;
+import org.openecomp.policy.rest.jpa.PdpEntity;
+import org.openecomp.policy.xacml.api.pap.EcompPDP;
+import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
+
+import com.att.research.xacml.api.pap.PAPException;
+//import com.att.research.xacml.api.pap.PDP;
+//import com.att.research.xacml.api.pap.PDPGroup;
+
+public interface PolicyDBDaoTransaction {
+
+	/**
+	 * Commits (makes permanent) the current transaction. Also, notifies other PolicyDBDao instances on other PAP servers of the update.
+	 * @throws IllegalStateException if the PolicyDBDao transaction has not been used or has been committed already.
+	 * @throws PersistenceException if the commit fails for some reason
+	 */
+	public void commitTransaction();
+	
+	/**
+	 * Create or update a policy
+	 * @param policy A Policy object representing the policy to store or update
+	 * @param username A string of the username you want to be stored for doing this operation
+	 * @throws IllegalStateException If a transaction is open that has not yet been committed
+	 * @throws PersistenceException If a database error occurs
+	 * @throws IllegalArgumentException If the Policy's PolicyRestAdapter contains incorrect data.
+	 */
+	public void createPolicy(Policy policy, String username) throws IllegalStateException, PersistenceException, IllegalArgumentException;
+	
+	/**
+	 * Create or update a policy
+	 * @param filePath The file path of the policy xml file
+	 * @param username A string of the username you want to be stored for doing this operation
+	 * @throws IllegalStateException If a transaction is open that has not yet been committed
+	 * @throws PersistenceException If a database error occurs
+	 * @throws IllegalArgumentException If the file path is incorrect, or if it refers to a Config policy
+	 */
+	public void createPolicy(String filePath, String username) throws IllegalStateException, PersistenceException, IllegalArgumentException;
+	
+	/**
+	 * Check if the PolicyDBDaoTransaction is currently open
+	 * @return False if the PolicyDBDao transaction has not been used or has been committed already, true if it is open.
+	 */
+	public boolean isTransactionOpen();
+	
+	
+	
+	/**
+	 * Delete an existing policy
+	 * @param policyToDelete The file path of the policy to delete
+	 * @throws IllegalArgumentException If the file path given can not be parsed
+	 * @throws IllegalStateException If a transaction is open that has not yet been committed
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void deletePolicy(String policyToDelete) throws IllegalStateException, PersistenceException, IllegalArgumentException;
+	
+	/**
+	 * Rollback (undo) the current transaction.
+	 */
+	public void rollbackTransaction();
+	
+	/**
+	 * Close the PolicyDBDaoTransaction without rolling back or doing anything. Just used to close the EntityManager
+	 */
+	public void close();
+	
+	
+	/**
+	 * Create a new PDP group in the database
+	 * @param groupID The ID to name the new group (use PolicyDBDao.createNewPDPGroupId)
+	 * @param groupName The name to use for the new group
+	 * @param groupDescription Description of the new group (optional)
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void createGroup(String groupID, String groupName, String groupDescription, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Updates a group in the database with a new name of description
+	 * @param group The group with updated information. The id must match an existing group, but the name and description can be changed.
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs or if the group can not be found
+	 */
+	public void updateGroup(EcompPDPGroup group, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Updates a PDP in the database with new information
+	 * @param pdp The PDP to update
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs or if the pdp can not be found
+	 */
+	public void updatePdp(EcompPDP pdp, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Change the default group in the database to the group provided.
+	 * @param group The new group which should be set as default in the database
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void changeDefaultGroup(EcompPDPGroup group, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Moves a PDP to a new group.
+	 * @param pdp The PDP which is to be moved to a new group
+	 * @param group The new group which the PDP should be added to
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void movePdp(EcompPDP pdp, EcompPDPGroup group, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Add a new PDP to an existing group
+	 * @param pdpID The ID to name the new PDP
+	 * @param groupID The ID of the existing group to add the PDP to
+	 * @param pdpName The name to use for the new PDP
+	 * @param pdpDescription Description of the new PDP (optional)
+	 * @param pdpJmxPort
+	 * @param username Username of the user performing the operation
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	/**
+	 * Add an existing policy to an existing group
+	 * @param group The ID of the existing group to add the policy to
+	 * @param policyID The ID of an existing policy
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void addPolicyToGroup(String group, String policyID, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	
+	/**
+	 * Delete an existing PDP group
+	 * @param group A PDPGroup object representing the group to delete
+	 * @param moveToGroup A PDPGroup object representing another existing group which PDPs in the group being deleted should be moved to
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 * @throws PAPException If an error relating to how groups are handled occurs
+	 */
+	public void deleteGroup(EcompPDPGroup group, EcompPDPGroup moveToGroup, String username)throws IllegalArgumentException, IllegalStateException, PersistenceException, PAPException;
+	
+	/**
+	 * Removes an existing PDP from its group and deletes it.
+	 * @param pdpID The ID of the existing PDP which should be deleted
+	 * @throws IllegalArgumentException If non-optional parameters are null or empty strings
+	 * @throws IllegalStateException If a transaction is already open
+	 * @throws PersistenceException If a database error occurs
+	 */
+	public void removePdpFromGroup(String pdpID, String username) throws IllegalArgumentException, IllegalStateException, PersistenceException;
+	
+	public GroupEntity getGroup(long groupKey);
+	public GroupEntity getGroup(String groupId);
+	public List<?> getPdpsInGroup(long groupKey);
+	public PdpEntity getPdp(long pdpKey);
+
+	void renamePolicy(String oldPath, String newPath,String username);
+
+	void clonePolicy(String oldPolicyPath, String newPolicyPath, String username);
+		
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/package-info.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/package-info.java
new file mode 100644
index 0000000..98e1bd9
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * 
+ */
+/**
+ *
+ */
+package org.openecomp.policy.pap.xacml.rest.components;
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ActionPolicyDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ActionPolicyDictionaryController.java
new file mode 100644
index 0000000..fa00fc1
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ActionPolicyDictionaryController.java
@@ -0,0 +1,201 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.ActionPolicyDictDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.ActionPolicyDict;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class ActionPolicyDictionaryController {
+
+	@Autowired
+	ActionPolicyDictDao actionPolicyDictDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+	
+	@RequestMapping(value={"/get_ActionPolicyDictDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getActionEntitybyName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("actionPolicyDictionaryDatas", mapper.writeValueAsString(actionPolicyDictDao.getActionDictDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	@RequestMapping(value={"/get_ActionPolicyDictData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getActionPolicyDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("actionPolicyDictionaryDatas", mapper.writeValueAsString(actionPolicyDictDao.getActionDictData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/action_dictionary/save_ActionDict.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveActionPolicyDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ActionPolicyDict actionPolicyDict = (ActionPolicyDict)mapper.readValue(root.get("actionPolicyDictionaryData").toString(), ActionPolicyDict.class);
+			ActionAdapter adapter = mapper.readValue(root.get("actionPolicyDictionaryData").toString(), ActionAdapter.class);
+			String userId = root.get("loginId").textValue();
+			String header = "";
+			int counter = 0;
+			if(adapter.getHeaders().size() > 0){
+				for(Object attribute : adapter.getHeaders()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						String value = ((LinkedHashMap<?, ?>) attribute).get("number").toString();
+						if(counter>0){
+							header = header + ":";
+						}
+						header = header + key + "=";
+						header = header + value;
+						counter ++;
+					}
+				}
+			}
+			actionPolicyDict.setHeader(header);
+			if(actionPolicyDict.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(actionPolicyDict.getAttributeName(), "attributeName", ActionPolicyDict.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					actionPolicyDict.setUserCreatedBy(this.getUserInfo(userId));
+					actionPolicyDict.setUserModifiedBy(this.getUserInfo(userId));
+					actionPolicyDictDao.Save(actionPolicyDict);
+				}
+			}else{
+				actionPolicyDict.setUserModifiedBy(this.getUserInfo(userId));
+				actionPolicyDictDao.update(actionPolicyDict); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.actionPolicyDictDao.getActionDictData());
+			}	 
+			JSONObject j = new JSONObject("{actionPolicyDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/action_dictionary/remove_actionPolicyDict.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeActionPolicyDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ActionPolicyDict actionPolicyDict = (ActionPolicyDict)mapper.readValue(root.get("data").toString(), ActionPolicyDict.class);
+			actionPolicyDictDao.delete(actionPolicyDict);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.actionPolicyDictDao.getActionDictData());
+			JSONObject j = new JSONObject("{actionPolicyDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+}
+
+class ActionAdapter{
+	private ArrayList<Object> headers;
+
+	public ArrayList<Object> getHeaders() {
+		return headers;
+	}
+
+	public void setHeaders(ArrayList<Object> headers) {
+		this.headers = headers;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/BRMSDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/BRMSDictionaryController.java
new file mode 100644
index 0000000..bdf4d2c
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/BRMSDictionaryController.java
@@ -0,0 +1,183 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.BRMSParamTemplateDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.BRMSParamTemplate;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+@Controller
+public class BRMSDictionaryController{
+
+	@Autowired
+	BRMSParamTemplateDao brmsParamTemplateDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	private String rule;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+
+	@RequestMapping(value={"/get_BRMSParamDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getBRMSParamDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("brmsParamDictionaryDatas", mapper.writeValueAsString(brmsParamTemplateDao.getBRMSParamDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_BRMSParamData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getBRMSParamDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("brmsParamDictionaryDatas", mapper.writeValueAsString(brmsParamTemplateDao.getBRMSParamTemplateData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/brms_dictionary/set_BRMSParamData.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public void SetRuleData(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		StringWriter writer = new StringWriter();
+		IOUtils.copy(request.getInputStream() , writer, StandardCharsets.UTF_8);
+		String cleanStreamBoundary =  writer.toString().replaceFirst("------(.*)(?s).*octet-stream", "");
+		rule = cleanStreamBoundary.substring(0, cleanStreamBoundary.lastIndexOf("end")+4);
+	}
+	
+	@RequestMapping(value={"/brms_dictionary/save_BRMSParam.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveBRMSParamDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			BRMSParamTemplate bRMSParamTemplateData = (BRMSParamTemplate)mapper.readValue(root.get("brmsParamDictionaryData").toString(), BRMSParamTemplate.class);
+			String userId = root.get("loginId").textValue();
+			bRMSParamTemplateData.setRule(rule);
+			if(bRMSParamTemplateData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(bRMSParamTemplateData.getRuleName(), "ruleName", BRMSParamTemplate.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					bRMSParamTemplateData.setUserCreatedBy(this.getUserInfo(userId));
+					brmsParamTemplateDao.Save(bRMSParamTemplateData);
+				}	
+			}else{
+				brmsParamTemplateDao.update(bRMSParamTemplateData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.brmsParamTemplateDao.getBRMSParamTemplateData());
+			} 
+			JSONObject j = new JSONObject("{brmsParamDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/brms_dictionary/remove_brmsParam.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeBRMSParamDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			BRMSParamTemplate bRMSParamTemplateData = (BRMSParamTemplate)mapper.readValue(root.get("data").toString(), BRMSParamTemplate.class);
+			brmsParamTemplateDao.delete(bRMSParamTemplateData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.brmsParamTemplateDao.getBRMSParamTemplateData());
+			JSONObject j = new JSONObject("{brmsParamDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/CheckDictionaryDuplicateEntries.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/CheckDictionaryDuplicateEntries.java
new file mode 100644
index 0000000..e044340
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/CheckDictionaryDuplicateEntries.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+/*
+ * 
+ * 
+ * 
+ * */
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+public class CheckDictionaryDuplicateEntries {
+
+	private static final Log logger = LogFactory.getLog(CheckDictionaryDuplicateEntries.class);
+	
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public List<Object> CheckDuplicateEntry(String value, String columnName, Class class1) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<Object> data = null;
+		try {
+			Criteria cr = session.createCriteria(class1);
+			cr.add(Restrictions.eq(columnName,value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying for Duplicate Entries for Table"+e + class1);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ClosedLoopDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ClosedLoopDictionaryController.java
new file mode 100644
index 0000000..d70661f
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/ClosedLoopDictionaryController.java
@@ -0,0 +1,764 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.adapters.GridData;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.PEPOptionsDao;
+import org.openecomp.policy.rest.dao.ServiceDictionaryDao;
+import org.openecomp.policy.rest.dao.SiteDictionaryDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.dao.VNFTypeDao;
+import org.openecomp.policy.rest.dao.VSCLActionDao;
+import org.openecomp.policy.rest.dao.VarbindDictionaryDao;
+import org.openecomp.policy.rest.jpa.ClosedLoopD2Services;
+import org.openecomp.policy.rest.jpa.ClosedLoopSite;
+import org.openecomp.policy.rest.jpa.PEPOptions;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.openecomp.policy.rest.jpa.VNFType;
+import org.openecomp.policy.rest.jpa.VSCLAction;
+import org.openecomp.policy.rest.jpa.VarbindDictionary;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class ClosedLoopDictionaryController{
+
+	@Autowired
+	VSCLActionDao vsclActionDao;
+	
+	@Autowired
+	VNFTypeDao vnfTypeDao;
+	
+	@Autowired
+	PEPOptionsDao pepOptionsDao;
+	
+	@Autowired
+	VarbindDictionaryDao varbindDao;
+	
+	@Autowired
+	ServiceDictionaryDao closedLoopServiceDao;
+	
+	@Autowired
+	SiteDictionaryDao closedLoopSiteDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+	
+	
+	@RequestMapping(value={"/get_VSCLActionDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVSCLActionDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("vsclActionDictionaryDatas", mapper.writeValueAsString(vsclActionDao.getVsclActionDataByName()));
+			org.openecomp.policy.pap.xacml.rest.util.JsonMessage msg = new org.openecomp.policy.pap.xacml.rest.util.JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	
+	@RequestMapping(value={"/get_VSCLActionData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVSCLActionDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("vsclActionDictionaryDatas", mapper.writeValueAsString(vsclActionDao.getVSCLActionData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_VNFTypeDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVNFTypeDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("vnfTypeDictionaryDatas", mapper.writeValueAsString(vnfTypeDao.getVNFTypeDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+		
+	@RequestMapping(value={"/get_VNFTypeData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVNFTypeDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("vnfTypeDictionaryDatas", mapper.writeValueAsString(vnfTypeDao.getVNFTypeData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PEPOptionsDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPEPOptionsDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("pepOptionsDictionaryDatas", mapper.writeValueAsString(pepOptionsDao.getPEPOptionsDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PEPOptionsData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPEPOptionsDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("pepOptionsDictionaryDatas", mapper.writeValueAsString(pepOptionsDao.getPEPOptionsData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_VarbindDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVarbindDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("varbindDictionaryDatas", mapper.writeValueAsString(varbindDao.getVarbindDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_VarbindDictionaryData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getVarbindDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("varbindDictionaryDatas", mapper.writeValueAsString(varbindDao.getVarbindDictionaryData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ClosedLoopServicesDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getClosedLoopServiceDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("closedLoopServiceDictionaryDatas", mapper.writeValueAsString(closedLoopServiceDao.getCLServiceDictDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ClosedLoopServicesData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getClosedLoopServiceDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("closedLoopServiceDictionaryDatas", mapper.writeValueAsString(closedLoopServiceDao.getClosedLoopD2ServicesData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ClosedLoopSiteDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getClosedLoopSiteDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("closedLoopSiteDictionaryDatas", mapper.writeValueAsString(closedLoopSiteDao.getCLSiteDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ClosedLoopSiteData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getClosedLoopSiteDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("closedLoopSiteDictionaryDatas", mapper.writeValueAsString(closedLoopSiteDao.getClosedLoopSiteData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/cl_dictionary/save_vsclAction.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView saveVSCLAction(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+		      ObjectMapper mapper = new ObjectMapper();
+		      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		      JsonNode root = mapper.readTree(request.getReader());
+		      VSCLAction vSCLAction = (VSCLAction)mapper.readValue(root.get("vsclActionDictionaryData").toString(), VSCLAction.class);
+		      String userId = root.get("loginId").textValue();
+		      if(vSCLAction.getId() == 0){
+		    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+		    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(vSCLAction.getVsclaction(), "vsclaction", VSCLAction.class);
+		    	  if(!duplicateData.isEmpty()){
+		    		  duplicateflag = true;
+		    	  }else{
+		    		  vSCLAction.setUserCreatedBy(this.getUserInfo(userId));
+		    		  vSCLAction.setUserModifiedBy(this.getUserInfo(userId));
+		    		  vsclActionDao.Save(vSCLAction);
+		    	  }
+		      }else{
+		    	  vSCLAction.setUserModifiedBy(this.getUserInfo(userId));
+		    	  vsclActionDao.update(vSCLAction); 
+		      } 
+		      response.setCharacterEncoding("UTF-8");
+		      response.setContentType("application / json");
+		      request.setCharacterEncoding("UTF-8");
+		      
+		      PrintWriter out = response.getWriter();
+		      String responseString = "";
+			  if(duplicateflag){
+				responseString = "Duplicate";
+			  }else{
+				responseString = mapper.writeValueAsString(this.vsclActionDao.getVSCLActionData());
+			  }	  
+		      JSONObject j = new JSONObject("{vsclActionDictionaryDatas: " + responseString + "}");
+		      
+		      out.write(j.toString());
+		      
+		      return null;
+	    }
+	    catch (Exception e){
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_VsclAction.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removeVSCLAction(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      VSCLAction vSCLAction = (VSCLAction)mapper.readValue(root.get("data").toString(), VSCLAction.class);
+	      vsclActionDao.delete(vSCLAction);
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      
+	      String responseString = mapper.writeValueAsString(this.vsclActionDao.getVSCLActionData());
+	      JSONObject j = new JSONObject("{vsclActionDictionaryDatas: " + responseString + "}");
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      System.out.println(e);
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/save_vnfType.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView saveVnfType(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      VNFType vNFType = (VNFType)mapper.readValue(root.get("vnfTypeDictionaryData").toString(), VNFType.class);
+		  String userId = root.get("loginId").textValue();
+	      if(vNFType.getId() == 0){
+	    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+	    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(vNFType.getVnftype(), "vnftype", VNFType.class);
+	    	  if(!duplicateData.isEmpty()){
+	    	  	duplicateflag = true;
+	    	  }else{
+	    		  vNFType.setUserCreatedBy(this.getUserInfo(userId));
+		    	  vNFType.setUserModifiedBy(this.getUserInfo(userId));
+		    	  vnfTypeDao.Save(vNFType);
+	    	  }  	 
+	      }else{
+	    	  vNFType.setUserModifiedBy(this.getUserInfo(userId));
+	    	  vnfTypeDao.update(vNFType); 
+	      } 
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.vnfTypeDao.getVNFTypeData());
+			} 
+	      JSONObject j = new JSONObject("{vnfTypeDictionaryDatas: " + responseString + "}");
+	      
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_vnfType.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removeVnfType(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+		      ObjectMapper mapper = new ObjectMapper();
+		      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		      JsonNode root = mapper.readTree(request.getReader());
+		      VNFType vNFType = (VNFType)mapper.readValue(root.get("data").toString(), VNFType.class);
+		      vnfTypeDao.delete(vNFType);
+		      response.setCharacterEncoding("UTF-8");
+		      response.setContentType("application / json");
+		      request.setCharacterEncoding("UTF-8");
+		      
+		      PrintWriter out = response.getWriter();
+		      
+		      String responseString = mapper.writeValueAsString(this.vnfTypeDao.getVNFTypeData());
+		      JSONObject j = new JSONObject("{vnfTypeDictionaryDatas: " + responseString + "}");
+		      out.write(j.toString());
+		      
+		      return null;
+		    }
+		    catch (Exception e){
+		      System.out.println(e);
+		      response.setCharacterEncoding("UTF-8");
+		      request.setCharacterEncoding("UTF-8");
+		      PrintWriter out = response.getWriter();
+		      out.write(e.getMessage());
+		    }
+		    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/save_pepOptions.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView savePEPOptions(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+		      ObjectMapper mapper = new ObjectMapper();
+		      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		      JsonNode root = mapper.readTree(request.getReader());
+		      PEPOptions pEPOptions = (PEPOptions)mapper.readValue(root.get("pepOptionsDictionaryData").toString(), PEPOptions.class);
+		      GridData gridData = (GridData)mapper.readValue(root.get("pepOptionsDictionaryData").toString(), GridData.class);
+		      String userId = root.get("loginId").textValue();
+		      String actions = "";
+				int counter = 0;
+				if(gridData.getAttributes().size() > 0){
+					for(Object attribute : gridData.getAttributes()){
+						if(attribute instanceof LinkedHashMap<?, ?>){
+							String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+							String value = ((LinkedHashMap<?, ?>) attribute).get("number").toString();
+							if(counter>0){
+								actions = actions + ":#@";
+							}
+							actions = actions + key + "=#@";
+							actions = actions + value;
+							counter ++;
+						}
+					}
+				}
+				pEPOptions.setActions(actions);
+		      if(pEPOptions.getId() == 0){
+		    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+		    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(pEPOptions.getPepName(), "pepName", PEPOptions.class);
+		    	  if(!duplicateData.isEmpty()){
+		    	  	duplicateflag = true;
+		    	  }else{
+		    		  pEPOptions.setUserCreatedBy(this.getUserInfo(userId));
+			    	  pEPOptions.setUserModifiedBy(this.getUserInfo(userId));
+			    	  pepOptionsDao.Save(pEPOptions);
+		    	  }   	 
+		      }else{
+		    	  pEPOptions.setUserModifiedBy(this.getUserInfo(userId));
+		    	  pepOptionsDao.update(pEPOptions); 
+		      } 
+		      response.setCharacterEncoding("UTF-8");
+		      response.setContentType("application / json");
+		      request.setCharacterEncoding("UTF-8");
+		      
+		      PrintWriter out = response.getWriter();
+		      String responseString = "";
+		      if(duplicateflag){
+		      	responseString = "Duplicate";
+		      }else{
+		    	  responseString = mapper.writeValueAsString(this.pepOptionsDao.getPEPOptionsData());
+		      } 
+		      JSONObject j = new JSONObject("{pepOptionsDictionaryDatas: " + responseString + "}");
+		      
+		      out.write(j.toString());
+		      
+		      return null;
+		    }
+		    catch (Exception e){
+		      response.setCharacterEncoding("UTF-8");
+		      request.setCharacterEncoding("UTF-8");
+		      PrintWriter out = response.getWriter();
+		      out.write(e.getMessage());
+		    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_pepOptions.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removePEPOptions(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      PEPOptions pEPOptions = (PEPOptions)mapper.readValue(root.get("data").toString(), PEPOptions.class);
+	      pepOptionsDao.delete(pEPOptions);
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      
+	      String responseString = mapper.writeValueAsString(this.pepOptionsDao.getPEPOptionsData());
+	      JSONObject j = new JSONObject("{pepOptionsDictionaryDatas: " + responseString + "}");
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      System.out.println(e);
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/save_service.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView saveServiceType(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      ClosedLoopD2Services serviceData = (ClosedLoopD2Services)mapper.readValue(root.get("closedLoopServiceDictionaryData").toString(), ClosedLoopD2Services.class);
+	      String userId = root.get("loginId").textValue();
+	      if(serviceData.getId() == 0){
+	    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+	    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(serviceData.getServiceName(), "serviceName", ClosedLoopD2Services.class);
+	    	  if(!duplicateData.isEmpty()){
+	    	  	duplicateflag = true;
+	    	  }else{
+	    		  serviceData.setUserCreatedBy(this.getUserInfo(userId));
+		    	  serviceData.setUserModifiedBy(this.getUserInfo(userId));
+		    	  closedLoopServiceDao.Save(serviceData);
+	    	  }
+	      }else{
+	    	  serviceData.setUserModifiedBy(this.getUserInfo(userId));
+	    	  closedLoopServiceDao.update(serviceData); 
+	      } 
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      String responseString = "";
+	      if(duplicateflag){
+	      	responseString = "Duplicate";
+	      }else{
+	    	  responseString = mapper.writeValueAsString(this.closedLoopServiceDao.getClosedLoopD2ServicesData());
+	      } 
+	      JSONObject j = new JSONObject("{closedLoopServiceDictionaryDatas: " + responseString + "}");
+	      
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_Service.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removeServiceType(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      ClosedLoopD2Services closedLoopD2Services = (ClosedLoopD2Services)mapper.readValue(root.get("data").toString(), ClosedLoopD2Services.class);
+	      closedLoopServiceDao.delete(closedLoopD2Services);
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      
+	      String responseString = mapper.writeValueAsString(this.closedLoopServiceDao.getClosedLoopD2ServicesData());
+	      JSONObject j = new JSONObject("{closedLoopServiceDictionaryDatas: " + responseString + "}");
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      System.out.println(e);
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/save_siteName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView saveSiteType(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      ClosedLoopSite siteData = (ClosedLoopSite)mapper.readValue(root.get("closedLoopSiteDictionaryData").toString(), ClosedLoopSite.class);
+	      String userId = root.get("loginId").textValue();
+	      if(siteData.getId() == 0){
+	    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+	    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(siteData.getSiteName(), "siteName", ClosedLoopSite.class);
+	    	  if(!duplicateData.isEmpty()){
+	    	  	duplicateflag = true;
+	    	  }else{
+	    		  siteData.setUserCreatedBy(this.getUserInfo(userId));
+		    	  siteData.setUserModifiedBy(this.getUserInfo(userId));
+		    	  closedLoopSiteDao.Save(siteData);
+	    	  }
+	      }else{
+	    	  siteData.setUserModifiedBy(this.getUserInfo(userId));
+	    	  closedLoopSiteDao.update(siteData); 
+	      } 
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      String responseString = "";
+	      if(duplicateflag){
+	      	responseString = "Duplicate";
+	      }else{
+	      	responseString = mapper.writeValueAsString(this.closedLoopSiteDao.getClosedLoopSiteData());
+	      }	
+	      JSONObject j = new JSONObject("{closedLoopSiteDictionaryDatas: " + responseString + "}");
+	      
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_site.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removeSiteType(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      ClosedLoopSite closedLoopSite = (ClosedLoopSite)mapper.readValue(root.get("data").toString(), ClosedLoopSite.class);
+	      closedLoopSiteDao.delete(closedLoopSite);
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      
+	      String responseString = mapper.writeValueAsString(this.closedLoopSiteDao.getClosedLoopSiteData());
+	      JSONObject j = new JSONObject("{closedLoopSiteDictionaryDatas: " + responseString + "}");
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      System.out.println(e);
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/save_varbind.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView saveVarbind(HttpServletRequest request, HttpServletResponse response) throws Exception{
+	    try {
+	    	boolean duplicateflag = false;
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      VarbindDictionary varbindDictionary = (VarbindDictionary)mapper.readValue(root.get("varbindDictionaryData").toString(), VarbindDictionary.class);
+	      String userId = root.get("loginId").textValue();
+	      if(varbindDictionary.getId() == 0){
+	    	  CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+	    	  List<Object> duplicateData =  entry.CheckDuplicateEntry(varbindDictionary.getVarbindName(), "varbindName", VarbindDictionary.class);
+	    	  if(!duplicateData.isEmpty()){
+	    	  	duplicateflag = true;
+	    	  }else{
+	    		  varbindDictionary.setUserCreatedBy(this.getUserInfo(userId));
+		    	  varbindDictionary.setUserModifiedBy(this.getUserInfo(userId));
+		    	  varbindDao.Save(varbindDictionary);
+	    	  }	  
+	      }else{
+	    	  varbindDictionary.setUserModifiedBy(this.getUserInfo(userId));
+	    	  varbindDao.update(varbindDictionary); 
+	      } 
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      String responseString = "";
+	      if(duplicateflag){
+	      	responseString = "Duplicate";
+	      }else{
+	      	responseString = mapper.writeValueAsString(this.varbindDao.getVarbindDictionaryData());
+	      }
+	      JSONObject j = new JSONObject("{varbindDictionaryDatas: " + responseString + "}");
+	      
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+	@RequestMapping(value={"/cl_dictionary/remove_varbindDict.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	  public ModelAndView removeVarbind(HttpServletRequest request, HttpServletResponse response) throws Exception {
+	    try{
+	      ObjectMapper mapper = new ObjectMapper();
+	      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+	      JsonNode root = mapper.readTree(request.getReader());
+	      VarbindDictionary varbindDictionary = (VarbindDictionary)mapper.readValue(root.get("data").toString(), VarbindDictionary.class);
+	      varbindDao.delete(varbindDictionary);
+	      response.setCharacterEncoding("UTF-8");
+	      response.setContentType("application / json");
+	      request.setCharacterEncoding("UTF-8");
+	      
+	      PrintWriter out = response.getWriter();
+	      
+	      String responseString = mapper.writeValueAsString(this.varbindDao.getVarbindDictionaryData());
+	      JSONObject j = new JSONObject("{varbindDictionaryDatas: " + responseString + "}");
+	      out.write(j.toString());
+	      
+	      return null;
+	    }
+	    catch (Exception e){
+	      System.out.println(e);
+	      response.setCharacterEncoding("UTF-8");
+	      request.setCharacterEncoding("UTF-8");
+	      PrintWriter out = response.getWriter();
+	      out.write(e.getMessage());
+	    }
+	    return null;
+	  }
+	
+}
+
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DecisionPolicyDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DecisionPolicyDictionaryController.java
new file mode 100644
index 0000000..3308a99
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DecisionPolicyDictionaryController.java
@@ -0,0 +1,188 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.DecisionPolicyDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.DecisionSettings;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class DecisionPolicyDictionaryController {
+
+	@Autowired
+	DecisionPolicyDao decisionPolicyDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+	
+	@RequestMapping(value={"/get_SettingsDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getSettingsDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("settingsDictionaryDatas", mapper.writeValueAsString(decisionPolicyDao.getDecisionDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	
+	@RequestMapping(value={"/get_SettingsDictionaryData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getSettingsDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("settingsDictionaryDatas", mapper.writeValueAsString(decisionPolicyDao.getDecisionSettingsData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/decision_dictionary/save_Settings.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveSettingsDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DecisionSettings decisionSettings = (DecisionSettings)mapper.readValue(root.get("settingsDictionaryData").toString(), DecisionSettings.class);
+		    String userId = root.get("loginId").textValue();
+			if(decisionSettings.getDatatypeBean().getShortName() != null){
+				String datatype = decisionSettings.getDatatypeBean().getShortName();
+				Datatype a = new Datatype();
+				if(datatype.equalsIgnoreCase("string")){
+					a.setId(26);	
+				}else if(datatype.equalsIgnoreCase("integer")){
+					a.setId(12);	
+				}else if(datatype.equalsIgnoreCase("boolean")){
+					a.setId(18);	
+				}else if(datatype.equalsIgnoreCase("double")){
+					a.setId(25);	
+				}else if(datatype.equalsIgnoreCase("user")){
+					a.setId(29);	
+				}
+				decisionSettings.setDatatypeBean(a);
+			}
+			if(decisionSettings.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(decisionSettings.getXacmlId(), "xacmlId", DecisionSettings.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					decisionSettings.setUserCreatedBy(this.getUserInfo(userId));
+					decisionSettings.setUserModifiedBy(this.getUserInfo(userId));
+					decisionPolicyDao.Save(decisionSettings);
+				}
+			}else{
+				decisionSettings.setUserModifiedBy(this.getUserInfo(userId));
+				decisionPolicyDao.update(decisionSettings); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString =  mapper.writeValueAsString(this.decisionPolicyDao.getDecisionSettingsData());
+			}
+			JSONObject j = new JSONObject("{settingsDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/settings_dictionary/remove_settings.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeSettingsDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DecisionSettings decisionSettings = (DecisionSettings)mapper.readValue(root.get("data").toString(), DecisionSettings.class);
+			decisionPolicyDao.delete(decisionSettings);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.decisionPolicyDao.getDecisionSettingsData());
+			JSONObject j = new JSONObject("{settingsDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DescriptiveDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DescriptiveDictionaryController.java
new file mode 100644
index 0000000..c184464
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DescriptiveDictionaryController.java
@@ -0,0 +1,190 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.adapters.GridData;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.DescriptiveScopeDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.DescriptiveScope;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class DescriptiveDictionaryController {
+
+	@Autowired
+	DescriptiveScopeDao descriptiveScopeDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+
+	@RequestMapping(value={"/get_DescriptiveScopeByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getDescriptiveDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("descriptiveScopeDictionaryDatas", mapper.writeValueAsString(descriptiveScopeDao.getDescriptiveScopeDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_DescriptiveScope"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getDescriptiveDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("descriptiveScopeDictionaryDatas", mapper.writeValueAsString(descriptiveScopeDao.getDescriptiveScope()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/descriptive_dictionary/save_descriptive.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveDescriptiveDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DescriptiveScope descriptiveScope = (DescriptiveScope)mapper.readValue(root.get("descriptiveScopeDictionaryData").toString(), DescriptiveScope.class);
+			GridData data = (GridData)mapper.readValue(root.get("descriptiveScopeDictionaryData").toString(), GridData.class);
+		    String userId = root.get("loginId").textValue();
+			String header = "";
+			int counter = 0;
+			if(data.getAttributes().size() > 0){
+				for(Object attribute : data.getAttributes()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						String value = ((LinkedHashMap<?, ?>) attribute).get("number").toString();
+						if(counter>0){
+							header = header + "AND";
+						}
+						header = header + key + ":";
+						header = header + value;
+						counter ++;
+					}
+				}
+			}
+			descriptiveScope.setSearch(header);
+			if(descriptiveScope.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(descriptiveScope.getScopeName(), "descriptiveScopeName", DescriptiveScope.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					descriptiveScope.setUserCreatedBy(this.getUserInfo(userId));
+					descriptiveScope.setUserModifiedBy(this.getUserInfo(userId));
+					descriptiveScopeDao.Save(descriptiveScope);
+				}
+			}else{
+				descriptiveScope.setUserModifiedBy(this.getUserInfo(userId));
+				descriptiveScopeDao.update(descriptiveScope); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString =  mapper.writeValueAsString(this.descriptiveScopeDao.getDescriptiveScope());
+			}
+			JSONObject j = new JSONObject("{descriptiveScopeDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/descriptive_dictionary/remove_descriptiveScope.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeDescriptiveDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DescriptiveScope descriptiveScope = (DescriptiveScope)mapper.readValue(root.get("data").toString(), DescriptiveScope.class);
+			descriptiveScopeDao.delete(descriptiveScope);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.descriptiveScopeDao.getDescriptiveScope());
+			JSONObject j = new JSONObject("{descriptiveScopeDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+}
+
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryController.java
new file mode 100644
index 0000000..aa2fb4a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryController.java
@@ -0,0 +1,366 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.AttributeDao;
+import org.openecomp.policy.rest.dao.CategoryDao;
+import org.openecomp.policy.rest.dao.EcompNameDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.Attribute;
+import org.openecomp.policy.rest.jpa.Category;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.EcompName;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class DictionaryController {
+	
+	private static final Log logger	= LogFactory.getLog(DictionaryController.class);
+
+	@Autowired
+	AttributeDao attributeDao;
+
+	@Autowired
+	EcompNameDao ecompNameDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	@Autowired
+	CategoryDao categoryDao;
+	
+	
+	public Category getCategory(){
+		for (int i = 0; i < categoryDao.getCategoryListData().size() ; i++) {
+			Category value = categoryDao.getCategoryListData().get(i);
+			if (value.getShortName().equals("resource")) {
+				return value;
+			}
+		}
+		return null;	
+	}
+	
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+
+	@RequestMapping(value={"/get_AttributeDatabyAttributeName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getAttributeDictionaryEntityDatabyAttributeName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			System.out.println();
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("attributeDictionaryDatas", mapper.writeValueAsString(attributeDao.getAttributeData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	//Attribute Dictionary
+	@RequestMapping(value="/get_AttributeData", method= RequestMethod.GET , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getAttributeDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			System.out.println();
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("attributeDictionaryDatas", mapper.writeValueAsString(attributeDao.getData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/attribute_dictionary/save_attribute.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveAttributeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			Attribute attributeData = (Attribute)mapper.readValue(root.get("attributeDictionaryData").toString(), Attribute.class);
+			AttributeValues attributeValueData = (AttributeValues)mapper.readValue(root.get("attributeDictionaryData").toString(), AttributeValues.class);
+			String userId = root.get("loginId").textValue();
+			String userValue = "";
+			int counter = 0;
+			if(attributeValueData.getUserDataTypeValues().size() > 0){
+				for(Object attribute : attributeValueData.getUserDataTypeValues()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("attributeValues").toString();
+						if(counter>0){
+							userValue = userValue + ",";
+						}
+						userValue = userValue + key ;
+						counter ++;
+					}
+				}
+			}
+			attributeData.setAttributeValue(userValue);
+			if(attributeData.getDatatypeBean().getShortName() != null){
+				String datatype = attributeData.getDatatypeBean().getShortName();
+				Datatype a = new Datatype();
+				if(datatype.equalsIgnoreCase("string")){
+					a.setId(26);	
+				}else if(datatype.equalsIgnoreCase("integer")){
+					a.setId(12);	
+				}else if(datatype.equalsIgnoreCase("boolean")){
+					a.setId(18);	
+				}else if(datatype.equalsIgnoreCase("double")){
+					a.setId(25);	
+				}else if(datatype.equalsIgnoreCase("user")){
+					a.setId(29);	
+				}
+				attributeData.setDatatypeBean(a);
+			}
+			if(attributeData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(attributeData.getXacmlId(), "xacmlId", Attribute.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					attributeData.setCategoryBean(this.getCategory());
+					attributeData.setUserCreatedBy(this.getUserInfo(userId));
+					attributeData.setUserModifiedBy(this.getUserInfo(userId));
+					attributeDao.Save(attributeData);
+				}
+			}else{
+				attributeData.setUserModifiedBy(this.getUserInfo(userId));
+				attributeDao.update(attributeData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.attributeDao.getData());
+			}
+			JSONObject j = new JSONObject("{attributeDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/attribute_dictionary/remove_attribute.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeAttributeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			Attribute attributeData = (Attribute)mapper.readValue(root.get("data").toString(), Attribute.class);
+			attributeDao.delete(attributeData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.attributeDao.getData());
+			JSONObject j = new JSONObject("{attributeDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	//EcompName Dictionary
+	@RequestMapping(value={"/get_EcompNameDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getEcompNameDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		logger.info("get_EcompNameDataByName is called");
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("ecompNameDictionaryDatas", mapper.writeValueAsString(ecompNameDao.getEcompNameDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_EcompNameData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getEcompNameDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		logger.info("get_EcompNameData is called");
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("ecompNameDictionaryDatas", mapper.writeValueAsString(ecompNameDao.getEcompName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+			logger.error("ERROR While callinge DAO: " + e.getMessage());
+		}
+	}
+
+	@RequestMapping(value={"/ecomp_dictionary/save_ecompName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveEcompDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			System.out.println("DictionaryController:  saveEcompDictionary() is called");
+			logger.debug("DictionaryController:  saveEcompDictionary() is called");
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			EcompName ecompData = (EcompName)mapper.readValue(root.get("ecompNameDictionaryData").toString(), EcompName.class);
+			String userId = root.get("loginId").textValue();
+			System.out.println("the userId from the ecomp portal is: " + userId);
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getEcompName(), "ecompName", EcompName.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					ecompData.setUserCreatedBy(getUserInfo(userId));
+					ecompData.setUserModifiedBy(getUserInfo(userId));
+					System.out.println("DictionaryController:  got the user info now about to call Save() method on ecompNamedao");
+					ecompNameDao.Save(ecompData);
+				}
+			}else{
+				ecompData.setUserModifiedBy(this.getUserInfo(userId));
+				ecompNameDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.ecompNameDao.getEcompName());
+			}
+			JSONObject j = new JSONObject("{ecompNameDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ecomp_dictionary/remove_ecomp.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeEcompDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			EcompName ecompData = (EcompName)mapper.readValue(root.get("data").toString(), EcompName.class);
+			ecompNameDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.ecompNameDao.getEcompName());
+			JSONObject j = new JSONObject("{ecompNameDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+}
+
+class AttributeValues{
+	private ArrayList<Object> userDataTypeValues;
+
+	public ArrayList<Object> getUserDataTypeValues() {
+		return userDataTypeValues;
+	}
+
+	public void setUserDataTypeValues(ArrayList<Object> userDataTypeValues) {
+		this.userDataTypeValues = userDataTypeValues;
+	}
+}
+
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryImportController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryImportController.java
new file mode 100644
index 0000000..3ed8f5d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/DictionaryImportController.java
@@ -0,0 +1,617 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+ /*
+  * 
+  * 
+  * */
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.OutputStream;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.openecomp.policy.rest.dao.ActionListDao;
+import org.openecomp.policy.rest.dao.ActionPolicyDictDao;
+import org.openecomp.policy.rest.dao.AddressGroupDao;
+import org.openecomp.policy.rest.dao.AttributeDao;
+import org.openecomp.policy.rest.dao.BRMSParamTemplateDao;
+import org.openecomp.policy.rest.dao.DecisionPolicyDao;
+import org.openecomp.policy.rest.dao.DescriptiveScopeDao;
+import org.openecomp.policy.rest.dao.EcompNameDao;
+import org.openecomp.policy.rest.dao.PEPOptionsDao;
+import org.openecomp.policy.rest.dao.PortListDao;
+import org.openecomp.policy.rest.dao.PrefixListDao;
+import org.openecomp.policy.rest.dao.ProtocolListDao;
+import org.openecomp.policy.rest.dao.SecurityZoneDao;
+import org.openecomp.policy.rest.dao.ServiceDictionaryDao;
+import org.openecomp.policy.rest.dao.ServiceGroupDao;
+import org.openecomp.policy.rest.dao.ServiceListDao;
+import org.openecomp.policy.rest.dao.SiteDictionaryDao;
+import org.openecomp.policy.rest.dao.TermListDao;
+import org.openecomp.policy.rest.dao.VNFTypeDao;
+import org.openecomp.policy.rest.dao.VSCLActionDao;
+import org.openecomp.policy.rest.dao.VarbindDictionaryDao;
+import org.openecomp.policy.rest.dao.ZoneDao;
+import org.openecomp.policy.rest.jpa.ActionList;
+import org.openecomp.policy.rest.jpa.ActionPolicyDict;
+import org.openecomp.policy.rest.jpa.AddressGroup;
+import org.openecomp.policy.rest.jpa.Attribute;
+import org.openecomp.policy.rest.jpa.BRMSParamTemplate;
+import org.openecomp.policy.rest.jpa.Category;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.DecisionSettings;
+import org.openecomp.policy.rest.jpa.DescriptiveScope;
+import org.openecomp.policy.rest.jpa.EcompName;
+import org.openecomp.policy.rest.jpa.GroupServiceList;
+import org.openecomp.policy.rest.jpa.PEPOptions;
+import org.openecomp.policy.rest.jpa.PREFIXLIST;
+import org.openecomp.policy.rest.jpa.ProtocolList;
+import org.openecomp.policy.rest.jpa.SecurityZone;
+import org.openecomp.policy.rest.jpa.ServiceList;
+import org.openecomp.policy.rest.jpa.TermList;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.openecomp.policy.rest.jpa.VNFType;
+import org.openecomp.policy.rest.jpa.VSCLAction;
+import org.openecomp.policy.rest.jpa.VarbindDictionary;
+import org.openecomp.policy.rest.jpa.Zone;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import au.com.bytecode.opencsv.CSVReader;
+
+
+@Controller
+public class DictionaryImportController {
+	private String newFile;
+
+	@Autowired
+	AttributeDao attributeDao;
+
+	@Autowired
+	ActionPolicyDictDao  actionPolicyDictDao;
+
+	@Autowired
+	EcompNameDao ecompNameDao;
+
+	@Autowired
+	VNFTypeDao vnfTypeDao;
+
+	@Autowired
+	VSCLActionDao vsclActionDao;
+
+	@Autowired
+	PEPOptionsDao pepOptionsDao;
+
+	@Autowired
+	VarbindDictionaryDao varbindDao;
+
+	@Autowired
+	ServiceDictionaryDao closedLoopServiceDao;
+
+	@Autowired
+	SiteDictionaryDao closedLoopSiteDao;
+
+	@Autowired
+	DescriptiveScopeDao descriptiveScopeDao;
+
+	@Autowired
+	PrefixListDao prefixListDao;
+
+	@Autowired
+	PortListDao portListDao;
+
+	@Autowired
+	ProtocolListDao protocolListDao;
+
+	@Autowired
+	AddressGroupDao addressGroupDao;
+
+	@Autowired
+	ActionListDao actionListDao;
+
+	@Autowired
+	SecurityZoneDao securityZoneDao;
+
+	@Autowired
+	ServiceGroupDao serviceGroupDao;
+
+	@Autowired
+	ServiceListDao serviceListDao;
+
+	@Autowired
+	TermListDao termListDao;
+
+	@Autowired
+	ZoneDao zoneDao;
+
+	@Autowired
+	DecisionPolicyDao decisionSettingsDao;
+
+	@Autowired
+	BRMSParamTemplateDao brmsParamTemplateDao;
+
+	@RequestMapping(value={"/dictionary/import_dictionary.htm/*"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public void ImportDictionaryData(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		//JsonNode root = mapper.readTree(request.getReader());
+		String userId = request.getPathInfo().substring(request.getPathInfo().lastIndexOf("/")+1);
+		List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
+		for (FileItem item : items) {
+			File file = new File(item.getName());
+			OutputStream outputStream = new FileOutputStream(file);
+			IOUtils.copy(item.getInputStream(), outputStream);
+			outputStream.close();
+			this.newFile = file.toString();
+			CSVReader csvReader = new CSVReader(new FileReader(this.newFile));
+			List<String[]> dictSheet = csvReader.readAll();
+			if(item.getName().startsWith("Attribute")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					Attribute attribute = new Attribute("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("xacml_id") || dictSheet.get(0)[j].equalsIgnoreCase("Attribute ID")){
+							attribute.setXacmlId(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("priority")){
+							attribute.setPriority(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("datatype") || dictSheet.get(0)[j].equalsIgnoreCase("Data Type")){
+							Datatype dataType = new Datatype();
+							if(rows[j].equalsIgnoreCase("string")){
+								dataType.setId(26);
+							}else if(rows[j].equalsIgnoreCase("integer")){
+								dataType.setId(12);
+							}else if(rows[j].equalsIgnoreCase("double")){
+								dataType.setId(25);
+							}else if(rows[j].equalsIgnoreCase("boolean")){
+								dataType.setId(18);
+							}else if(rows[j].equalsIgnoreCase("user")){
+								dataType.setId(29);
+							}
+							attribute.setDatatypeBean(dataType);
+							Category category = new Category();
+							category.setId(5);
+							attribute.setCategoryBean(category);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("attribute_value") || dictSheet.get(0)[j].equalsIgnoreCase("Attribute Value")){
+							attribute.setAttributeValue(rows[j]);
+						}
+					}
+					attributeDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("ActionPolicyDictionary")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					ActionPolicyDict attribute = new ActionPolicyDict("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("attribute_name") || dictSheet.get(0)[j].equalsIgnoreCase("Attribute Name")){
+							attribute.setAttributeName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("body")){
+							attribute.setBody(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("headers")){
+							attribute.setHeader(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("method")){
+							attribute.setMethod(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("type")){
+							attribute.setMethod(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("url")){
+							attribute.setMethod(rows[j]);
+						}
+					}
+					actionPolicyDictDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("EcompName")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					EcompName attribute = new EcompName("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("ecomp_name") || dictSheet.get(0)[j].equalsIgnoreCase("Ecomp Name")){
+							attribute.setEcompName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					ecompNameDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("VNFType")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					VNFType attribute = new VNFType("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("vnf_type") || dictSheet.get(0)[j].equalsIgnoreCase("VNF Type")){
+							attribute.setVnftype(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					vnfTypeDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("VSCLAction")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					VSCLAction attribute = new VSCLAction("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("vscl_action") || dictSheet.get(0)[j].equalsIgnoreCase("VSCL Action")){
+							attribute.setVsclaction(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					vsclActionDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("PEPOptions")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					PEPOptions attribute = new PEPOptions("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("PEP_NAME") || dictSheet.get(0)[j].equalsIgnoreCase("PEP Name")){
+							attribute.setPepName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("Actions")){
+							attribute.setActions(rows[j]);
+						}
+					}
+					pepOptionsDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("VarbindDictionary")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					VarbindDictionary attribute = new VarbindDictionary("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("varbind_Name") || dictSheet.get(0)[j].equalsIgnoreCase("Varbind Name")){
+							attribute.setVarbindName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("varbind_Description") || dictSheet.get(0)[j].equalsIgnoreCase("Varbind Description")){
+							attribute.setVarbindDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("varbind_oid") || dictSheet.get(0)[j].equalsIgnoreCase("Varbind OID")){
+							attribute.setVarbindOID(rows[j]);
+						}
+					}
+					varbindDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("BRMSParamDictionary")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					BRMSParamTemplate attribute = new BRMSParamTemplate();
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("param_template_name") || dictSheet.get(0)[j].equalsIgnoreCase("Rule Name")){
+							attribute.setRuleName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("DESCRIPTION") || dictSheet.get(0)[j].equalsIgnoreCase("Description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("rule")){
+							attribute.setRule(rows[j]);
+						}
+					}
+					brmsParamTemplateDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("Settings")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					DecisionSettings attribute = new DecisionSettings("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("xacml_id") || dictSheet.get(0)[j].equalsIgnoreCase("Settings ID")){
+							attribute.setXacmlId(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("priority")){
+							attribute.setPriority(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("datatype") || dictSheet.get(0)[j].equalsIgnoreCase("Data Type")){
+							Datatype dataType = new Datatype();
+							if(rows[j].equalsIgnoreCase("string")){
+								dataType.setId(26);
+							}else if(rows[j].equalsIgnoreCase("integer")){
+								dataType.setId(12);
+							}else if(rows[j].equalsIgnoreCase("double")){
+								dataType.setId(25);
+							}else if(rows[j].equalsIgnoreCase("boolean")){
+								dataType.setId(18);
+							}else if(rows[j].equalsIgnoreCase("user")){
+								dataType.setId(29);
+							}
+							attribute.setDatatypeBean(dataType);
+						}
+					}
+					decisionSettingsDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("PrefixList")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					PREFIXLIST attribute = new PREFIXLIST("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("prefixListName") || dictSheet.get(0)[j].equalsIgnoreCase("PrefixList Name")){
+							attribute.setPrefixListName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setPrefixListValue(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("prefixListValue") || dictSheet.get(0)[j].equalsIgnoreCase("PrefixList Value")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					prefixListDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("SecurityZone")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					SecurityZone attribute = new SecurityZone("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("zoneName") || dictSheet.get(0)[j].equalsIgnoreCase("Zone Name")){
+							attribute.setZoneName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("zoneValue")  || dictSheet.get(0)[j].equalsIgnoreCase("Zone Value")){
+							attribute.setZoneValue(rows[j]);
+						}
+					}
+					securityZoneDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("Zone")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					Zone attribute = new Zone("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("zoneName") || dictSheet.get(0)[j].equalsIgnoreCase("Zone Name")){
+							attribute.setZoneName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("zoneValue")  || dictSheet.get(0)[j].equalsIgnoreCase("Zone Value")){
+							attribute.setZoneValue(rows[j]);
+						}
+					}
+					zoneDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("ServiceList")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					ServiceList attribute = new ServiceList("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceName") || dictSheet.get(0)[j].equalsIgnoreCase("Service Name")){
+							attribute.setServiceName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceDesc")  || dictSheet.get(0)[j].equalsIgnoreCase("Description")){
+							attribute.setServiceDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceType")  || dictSheet.get(0)[j].equalsIgnoreCase("Service Type")){
+							attribute.setServiceType(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceTrasProtocol")  || dictSheet.get(0)[j].equalsIgnoreCase("Transport Protocol")){
+							attribute.setServiceTransProtocol(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceAppProtocol")  || dictSheet.get(0)[j].equalsIgnoreCase("APP Protocol")){
+							attribute.setServiceAppProtocol(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("servicePorts")  || dictSheet.get(0)[j].equalsIgnoreCase("Ports")){
+							attribute.setServicePorts(rows[j]);
+						}
+					}
+					serviceListDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("ServiceGroup")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					GroupServiceList attribute = new GroupServiceList("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("name") || dictSheet.get(0)[j].equalsIgnoreCase("Group Name")){
+							attribute.setGroupName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceList")  || dictSheet.get(0)[j].equalsIgnoreCase("Service List")){
+							attribute.setServiceList(rows[j]);
+						}
+					}
+					serviceGroupDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("AddressGroup")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					AddressGroup attribute = new AddressGroup("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("name") || dictSheet.get(0)[j].equalsIgnoreCase("Group Name")){
+							attribute.setGroupName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("serviceList")  || dictSheet.get(0)[j].equalsIgnoreCase("Prefix List")){
+							attribute.setServiceList(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					addressGroupDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("ProtocolList")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					ProtocolList attribute = new ProtocolList("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("protocolName") || dictSheet.get(0)[j].equalsIgnoreCase("Protocol Name")){
+							attribute.setProtocolName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					protocolListDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("ActionList")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					ActionList attribute = new ActionList("",  userId);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("actionName") || dictSheet.get(0)[j].equalsIgnoreCase("Action Name")){
+							attribute.setActionName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+					}
+					actionListDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("TermList")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					TermList attribute = new TermList("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("termName") || dictSheet.get(0)[j].equalsIgnoreCase("Term-Name")){
+							attribute.setTermName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("Term-Description") || dictSheet.get(0)[j].equalsIgnoreCase("termDescription")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("fromZone")  || dictSheet.get(0)[j].equalsIgnoreCase("From Zone")){
+							attribute.setFromZones(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("toZone") || dictSheet.get(0)[j].equalsIgnoreCase("To Zone")){
+							attribute.setToZones(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("srcIPList") || dictSheet.get(0)[j].equalsIgnoreCase("Source-IP-List")){
+							attribute.setSrcIPList(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("destIPList") || dictSheet.get(0)[j].equalsIgnoreCase("Destination-IP-List")){
+							attribute.setDestIPList(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("srcPortList") || dictSheet.get(0)[j].equalsIgnoreCase("Source-Port-List")){
+							attribute.setSrcPortList(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("destPortList") || dictSheet.get(0)[j].equalsIgnoreCase("Destination-Port-List")){
+							attribute.setDestPortList(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("action") || dictSheet.get(0)[j].equalsIgnoreCase("Action List")){
+							attribute.setAction(rows[j]);
+						}
+					}
+					termListDao.Save(attribute);
+				}
+			}
+			if(item.getName().startsWith("SearchCriteria")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					DescriptiveScope attribute = new DescriptiveScope("",  userId);
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					attribute.setUserModifiedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if(dictSheet.get(0)[j].equalsIgnoreCase("descriptiveScopeName") || dictSheet.get(0)[j].equalsIgnoreCase("Descriptive ScopeName")){
+							attribute.setScopeName(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("description")){
+							attribute.setDescription(rows[j]);
+						}
+						if(dictSheet.get(0)[j].equalsIgnoreCase("search") || dictSheet.get(0)[j].equalsIgnoreCase("Search Criteria")){
+							attribute.setSearch(rows[j]);
+						}
+					}
+					descriptiveScopeDao.Save(attribute);
+				}
+			}
+			csvReader.close();
+		}
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/EnforcerDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/EnforcerDictionaryController.java
new file mode 100644
index 0000000..7bdb376
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/EnforcerDictionaryController.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.EnforcerPolicyDao;
+import org.openecomp.policy.rest.jpa.EnforcingType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class EnforcerDictionaryController {
+
+	@Autowired
+	EnforcerPolicyDao enforcerPolicyDao;
+
+	@RequestMapping(value={"/get_EnforcerTypeData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getEnforcerDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("enforcerDictionaryDatas", mapper.writeValueAsString(enforcerPolicyDao.getEnforcingTypeData()));
+			org.openecomp.policy.pap.xacml.rest.util.JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/enforcer_dictionary/save_enforcerType.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveEnforcerDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			EnforcingType enforcingType = (EnforcingType)mapper.readValue(root.get("enforcerDictionaryData").toString(), EnforcingType.class);
+			if(enforcingType.getId() == 0){
+				enforcerPolicyDao.Save(enforcingType);
+			}else{
+				enforcerPolicyDao.update(enforcingType); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = mapper.writeValueAsString(this.enforcerPolicyDao.getEnforcingTypeData());
+			JSONObject j = new JSONObject("{enforcerDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/enforcer_dictionary/remove_enforcer.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeEnforcerDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			EnforcingType enforcingType = (EnforcingType)mapper.readValue(root.get("data").toString(), EnforcingType.class);
+			enforcerPolicyDao.delete(enforcingType);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.enforcerPolicyDao.getEnforcingTypeData());
+			JSONObject j = new JSONObject("{enforcerDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/FirewallDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/FirewallDictionaryController.java
new file mode 100644
index 0000000..d2c3715
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/FirewallDictionaryController.java
@@ -0,0 +1,1578 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.netty.handler.ipfilter.CIDR;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.adapters.GridData;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.ActionListDao;
+import org.openecomp.policy.rest.dao.AddressGroupDao;
+import org.openecomp.policy.rest.dao.FirewallDictionaryListDao;
+import org.openecomp.policy.rest.dao.PortListDao;
+import org.openecomp.policy.rest.dao.PrefixListDao;
+import org.openecomp.policy.rest.dao.ProtocolListDao;
+import org.openecomp.policy.rest.dao.SecurityZoneDao;
+import org.openecomp.policy.rest.dao.ServiceGroupDao;
+import org.openecomp.policy.rest.dao.ServiceListDao;
+import org.openecomp.policy.rest.dao.TermListDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.dao.ZoneDao;
+import org.openecomp.policy.rest.jpa.ActionList;
+import org.openecomp.policy.rest.jpa.AddressGroup;
+import org.openecomp.policy.rest.jpa.FirewallDictionaryList;
+import org.openecomp.policy.rest.jpa.GroupServiceList;
+import org.openecomp.policy.rest.jpa.PREFIXLIST;
+import org.openecomp.policy.rest.jpa.PortList;
+import org.openecomp.policy.rest.jpa.ProtocolList;
+import org.openecomp.policy.rest.jpa.SecurityZone;
+import org.openecomp.policy.rest.jpa.ServiceList;
+import org.openecomp.policy.rest.jpa.TermList;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.openecomp.policy.rest.jpa.Zone;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+@Controller
+public class FirewallDictionaryController {
+
+	@Autowired
+	PrefixListDao prefixListDao;
+	
+	@Autowired
+	PortListDao portListDao;
+	
+	@Autowired
+	ProtocolListDao protocolListDao;
+	
+	@Autowired
+	AddressGroupDao addressGroupDao;
+	
+	@Autowired
+	ActionListDao actionListDao;
+	
+	@Autowired
+	SecurityZoneDao securityZoneDao;
+	
+	@Autowired
+	ServiceGroupDao serviceGroupDao;
+	
+	@Autowired
+	ServiceListDao serviceListDao;
+	
+	@Autowired
+	TermListDao termListDao;
+	
+	@Autowired
+	ZoneDao zoneDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	@Autowired
+	FirewallDictionaryListDao fwDictionaryListDao;
+	
+
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;		
+	}
+
+	@RequestMapping(value={"/get_PrefixListDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPrefixListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("prefixListDictionaryDatas", mapper.writeValueAsString(prefixListDao.getPrefixListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PrefixListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPrefixListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("prefixListDictionaryDatas", mapper.writeValueAsString(prefixListDao.getPREFIXLISTData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_prefixList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePrefixListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PREFIXLIST prefixList = (PREFIXLIST)mapper.readValue(root.get("prefixListDictionaryData").toString(), PREFIXLIST.class);
+			if(prefixList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(prefixList.getPrefixListName(), "prefixListName", PREFIXLIST.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					prefixListDao.Save(prefixList);
+				}		
+			}else{
+				prefixListDao.update(prefixList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.prefixListDao.getPREFIXLISTData());
+			}
+			JSONObject j = new JSONObject("{prefixListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_PrefixList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePrefixListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PREFIXLIST prefixList = (PREFIXLIST)mapper.readValue(root.get("data").toString(), PREFIXLIST.class);
+			prefixListDao.delete(prefixList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.prefixListDao.getPREFIXLISTData());
+			JSONObject j = new JSONObject("{prefixListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/validate_prefixList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView validatePrefixListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PREFIXLIST prefixList = (PREFIXLIST)mapper.readValue(root.get("prefixListDictionaryData").toString(), PREFIXLIST.class);
+			String responseValidation = "success";
+			 try{
+				 CIDR.newCIDR(prefixList.getPrefixListValue());
+			 }catch(UnknownHostException e){
+				 responseValidation = "error";
+				 //AdminNotification.warn("IP not according to CIDR notation");
+			 }		
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			JSONObject j = new JSONObject("{result: " + responseValidation + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_PortListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPortListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("portListDictionaryDatas", mapper.writeValueAsString(portListDao.getPortListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_portName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePortListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PortList portList = (PortList)mapper.readValue(root.get("portListDictionaryData").toString(), PortList.class);
+			if(portList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(portList.getPortName(), "portName", PortList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					portListDao.Save(portList);
+				}
+			}else{
+				portListDao.update(portList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.portListDao.getPortListData());
+			}
+			JSONObject j = new JSONObject("{portListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_PortList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePortListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PortList portList = (PortList)mapper.readValue(root.get("data").toString(), PortList.class);
+			portListDao.delete(portList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.portListDao.getPortListData());
+			JSONObject j = new JSONObject("{portListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_ProtocolListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getProtocolListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("protocolListDictionaryDatas", mapper.writeValueAsString(protocolListDao.getProtocolListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ProtocolListDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getProtocolListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("protocolListDictionaryDatas", mapper.writeValueAsString(protocolListDao.getProtocolListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_protocolList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveProtocolListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ProtocolList protocolList = (ProtocolList)mapper.readValue(root.get("protocolListDictionaryData").toString(), ProtocolList.class);
+			if(protocolList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(protocolList.getProtocolName(), "protocolName", ProtocolList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					protocolListDao.Save(protocolList);
+				}
+			}else{
+				protocolListDao.update(protocolList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.protocolListDao.getProtocolListData());
+			}
+			JSONObject j = new JSONObject("{protocolListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_protocol.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeProtocolListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ProtocolList protocolList = (ProtocolList)mapper.readValue(root.get("data").toString(), ProtocolList.class);
+			protocolListDao.delete(protocolList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.protocolListDao.getProtocolListData());
+			JSONObject j = new JSONObject("{protocolListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_AddressGroupDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getAddressGroupDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("addressGroupDictionaryDatas", mapper.writeValueAsString(addressGroupDao.getAddressGroupDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_AddressGroupData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getAddressGroupDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("addressGroupDictionaryDatas", mapper.writeValueAsString(addressGroupDao.getAddressGroupData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_addressGroup.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveAddressGroupDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			AddressGroup addressGroup = (AddressGroup)mapper.readValue(root.get("addressGroupDictionaryData").toString(), AddressGroup.class);
+			GridData gridData = (GridData)mapper.readValue(root.get("addressGroupDictionaryData").toString(), GridData.class);
+			if(!addressGroup.getGroupName().startsWith("Group_")){
+				String groupName = "Group_"+addressGroup.getGroupName();
+				addressGroup.setGroupName(groupName);
+			}
+			String userValue = "";
+			int counter = 0;
+			if(gridData.getAttributes().size() > 0){
+				for(Object attribute : gridData.getAttributes()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(counter>0){
+							userValue = userValue + ",";
+						}
+						userValue = userValue + key ;
+						counter ++;
+					}
+				}
+			}
+			addressGroup.setServiceList(userValue);
+			if(addressGroup.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(addressGroup.getGroupName(), "name", AddressGroup.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					addressGroupDao.Save(addressGroup);
+				}
+			}else{
+				addressGroupDao.update(addressGroup); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.addressGroupDao.getAddressGroupData());
+			}
+			JSONObject j = new JSONObject("{addressGroupDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_AddressGroup.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeAddressGroupDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			AddressGroup addressGroup = (AddressGroup)mapper.readValue(root.get("data").toString(), AddressGroup.class);
+			addressGroupDao.delete(addressGroup);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.addressGroupDao.getAddressGroupData());
+			JSONObject j = new JSONObject("{addressGroupDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_ActionListDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getActionListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("actionListDictionaryDatas", mapper.writeValueAsString(actionListDao.getActionListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ActionListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getActionListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("actionListDictionaryDatas", mapper.writeValueAsString(actionListDao.getActionListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_ActionList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveActionListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ActionList actionList = (ActionList)mapper.readValue(root.get("actionListDictionaryData").toString(), ActionList.class);
+			if(actionList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(actionList.getActionName(), "actionName", ActionList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					actionListDao.Save(actionList);
+				}
+			}else{
+				actionListDao.update(actionList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.actionListDao.getActionListData());
+			}
+			JSONObject j = new JSONObject("{actionListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_ActionList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeActionListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ActionList actionList = (ActionList)mapper.readValue(root.get("data").toString(), ActionList.class);
+			actionListDao.delete(actionList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.actionListDao.getActionListData());
+			JSONObject j = new JSONObject("{actionListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_ServiceGroupData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getServiceGroupDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("serviceGroupDictionaryDatas", mapper.writeValueAsString(serviceGroupDao.getGroupServiceListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ServiceGroupDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getServiceGroupDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("serviceGroupDictionaryDatas", mapper.writeValueAsString(serviceGroupDao.getGroupServiceDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_serviceGroup.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveServiceGroupDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			GroupServiceList groupServiceList = (GroupServiceList)mapper.readValue(root.get("serviceGroupDictionaryData").toString(), GroupServiceList.class);
+			GridData gridData = (GridData)mapper.readValue(root.get("serviceGroupDictionaryData").toString(), GridData.class);
+			if(!groupServiceList.getGroupName().startsWith("Group_")){
+				String groupName = "Group_"+groupServiceList.getGroupName();
+				groupServiceList.setGroupName(groupName);
+			}
+			String userValue = "";
+			int counter = 0;
+			if(gridData.getAttributes().size() > 0){
+				for(Object attribute : gridData.getAttributes()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(counter>0){
+							userValue = userValue + ",";
+						}
+						userValue = userValue + key ;
+						counter ++;
+					}
+				}
+			}
+			groupServiceList.setServiceList(userValue);
+			if(groupServiceList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(groupServiceList.getGroupName(), "name", GroupServiceList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					serviceGroupDao.Save(groupServiceList);
+				}
+			}else{
+				serviceGroupDao.update(groupServiceList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.serviceGroupDao.getGroupServiceListData());
+			}
+			JSONObject j = new JSONObject("{serviceGroupDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_serviceGroup.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeServiceGroupDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			GroupServiceList groupServiceList = (GroupServiceList)mapper.readValue(root.get("data").toString(), GroupServiceList.class);
+			serviceGroupDao.delete(groupServiceList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.serviceGroupDao.getGroupServiceListData());
+			JSONObject j = new JSONObject("{serviceGroupDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_SecurityZoneDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getSecurityZoneDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("securityZoneDictionaryDatas", mapper.writeValueAsString(securityZoneDao.getSecurityZoneDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_SecurityZoneData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getSecurityZoneDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("securityZoneDictionaryDatas", mapper.writeValueAsString(securityZoneDao.getSecurityZoneData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_securityZone.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveSecurityZoneDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			SecurityZone securityZone = (SecurityZone)mapper.readValue(root.get("securityZoneDictionaryData").toString(), SecurityZone.class);
+			if(securityZone.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(securityZone.getZoneName(), "zoneName", SecurityZone.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					securityZoneDao.Save(securityZone);
+				}			
+			}else{
+				securityZoneDao.update(securityZone); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.securityZoneDao.getSecurityZoneData());
+			}
+			JSONObject j = new JSONObject("{securityZoneDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_securityZone.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeSecurityZoneDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			SecurityZone securityZone = (SecurityZone)mapper.readValue(root.get("data").toString(), SecurityZone.class);
+			securityZoneDao.delete(securityZone);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.securityZoneDao.getSecurityZoneData());
+			JSONObject j = new JSONObject("{securityZoneDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	
+	@RequestMapping(value={"/get_ServiceListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getServiceListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("serviceListDictionaryDatas", mapper.writeValueAsString(serviceListDao.getServiceListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ServiceListDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getServiceListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("serviceListDictionaryDatas", mapper.writeValueAsString(serviceListDao.getServiceListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_serviceList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveServiceListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ServiceList serviceList = (ServiceList)mapper.readValue(root.get("serviceListDictionaryData").toString(), ServiceList.class);
+			GridData serviceListGridData = (GridData)mapper.readValue(root.get("serviceListDictionaryData").toString(), GridData.class);
+			String tcpValue = "";
+			int counter = 0;
+			if(serviceListGridData.getTransportProtocols().size() > 0){
+				for(Object attribute : serviceListGridData.getTransportProtocols()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(counter>0){
+							tcpValue = tcpValue + ",";
+						}
+						tcpValue = tcpValue + key ;
+						counter ++;
+					}
+				}
+			}
+			serviceList.setServiceTransProtocol(tcpValue);
+			String appValue = "";
+			int counter1 = 0;
+			if(serviceListGridData.getAppProtocols().size() > 0){
+				for(Object attribute : serviceListGridData.getAppProtocols()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(counter1>0){
+							appValue = appValue + ",";
+						}
+						appValue = appValue + key ;
+						counter1 ++;
+					}
+				}
+			}
+			serviceList.setServiceAppProtocol(appValue);
+			serviceList.setServiceType("SERVICE");
+			if(serviceList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(serviceList.getServiceName(), "serviceName", ServiceList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					serviceListDao.Save(serviceList);
+				}
+				
+			}else{
+				serviceListDao.update(serviceList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.serviceListDao.getServiceListData());
+			} 
+			JSONObject j = new JSONObject("{serviceListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_serviceList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeServiceListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			ServiceList serviceList = (ServiceList)mapper.readValue(root.get("data").toString(), ServiceList.class);
+			serviceListDao.delete(serviceList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.serviceListDao.getServiceListData());
+			JSONObject j = new JSONObject("{serviceListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_ZoneData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getZoneDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("zoneDictionaryDatas", mapper.writeValueAsString(zoneDao.getZoneData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_ZoneDictionaryDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getZoneDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("zoneDictionaryDatas", mapper.writeValueAsString(zoneDao.getZoneDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_zoneName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveZoneDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			Zone zone = (Zone)mapper.readValue(root.get("zoneDictionaryData").toString(), Zone.class);
+			if(zone.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(zone.getZoneName(), "zoneName", Zone.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					zoneDao.Save(zone);
+				}	
+			}else{
+				zoneDao.update(zone); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.zoneDao.getZoneData());
+			}
+			JSONObject j = new JSONObject("{zoneDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_zone.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeZoneDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			Zone zone = (Zone)mapper.readValue(root.get("data").toString(), Zone.class);
+			zoneDao.delete(zone);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.zoneDao.getZoneData());
+			JSONObject j = new JSONObject("{zoneDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_TermListDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getTermListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("termListDictionaryDatas", mapper.writeValueAsString(termListDao.getTermListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_TermListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getTermListDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("termListDictionaryDatas", mapper.writeValueAsString(termListDao.getTermListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_termList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveTermListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			TermList termList = (TermList)mapper.readValue(root.get("termListDictionaryData").toString(), TermList.class);
+			TermListData termListDatas = (TermListData)mapper.readValue(root.get("termListDictionaryData").toString(), TermListData.class);
+			String userId = root.get("loginId").textValue();
+			String fromZoneValue = "";
+			int counter = 0;
+			if(termListDatas.getFromZoneDatas().size() > 0){
+				for(Object fromZone : termListDatas.getFromZoneDatas()){
+					if(fromZone instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) fromZone).get("option").toString();
+						if(counter>0){
+							fromZoneValue = fromZoneValue + ",";
+						}
+						fromZoneValue = fromZoneValue + key ;
+						counter ++;
+					}
+				}
+			}
+			termList.setFromZones(fromZoneValue);
+			
+			String toZoneValue = "";
+			int toZonecounter = 0;
+			if(termListDatas.getToZoneDatas().size() > 0){
+				for(Object toZone : termListDatas.getToZoneDatas()){
+					if(toZone instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) toZone).get("option").toString();
+						if(toZonecounter>0){
+							toZoneValue = toZoneValue + ",";
+						}
+						toZoneValue = toZoneValue + key ;
+						toZonecounter ++;
+					}
+				}
+			}
+			termList.setToZones(toZoneValue);
+			
+			String srcListValues = "";
+			int srcListcounter = 0;
+			if(termListDatas.getSourceListDatas().size() > 0){
+				for(Object srcList : termListDatas.getSourceListDatas()){
+					if(srcList instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) srcList).get("option").toString();
+						if(srcListcounter>0){
+							srcListValues = srcListValues + ",";
+						}
+						srcListValues = srcListValues + key ;
+						srcListcounter ++;
+					}
+				}
+			}
+			termList.setSrcIPList(srcListValues);
+			
+			String desListValues = "";
+			int destListcounter = 0;
+			if(termListDatas.getDestinationListDatas().size() > 0){
+				for(Object desList : termListDatas.getDestinationListDatas()){
+					if(desList instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) desList).get("option").toString();
+						if(destListcounter>0){
+							desListValues = desListValues + ",";
+						}
+						desListValues = desListValues + key ;
+						destListcounter ++;
+					}
+				}
+			}
+			termList.setDestIPList(desListValues);
+			
+			String srcSerValue = "";
+			int srcSercounter = 0;
+			if(termListDatas.getSourceServiceDatas().size() > 0){
+				for(Object srcSrc : termListDatas.getSourceServiceDatas()){
+					if(srcSrc instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) srcSrc).get("option").toString();
+						if(srcSercounter>0){
+							srcSerValue = srcSerValue + ",";
+						}
+						srcSerValue = srcSerValue + key ;
+						srcSercounter ++;
+					}
+				}
+			}
+			termList.setSrcPortList(srcSerValue);
+			
+			String desSrcValue = "";
+			int desSrccounter = 0;
+			if(termListDatas.getDestinationServiceDatas().size() > 0){
+				for(Object desSrc : termListDatas.getDestinationServiceDatas()){
+					if(desSrc instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) desSrc).get("option").toString();
+						if(desSrccounter>0){
+							desSrcValue = desSrcValue + ",";
+						}
+						desSrcValue = desSrcValue + key ;
+						desSrccounter ++;
+					}
+				}
+			}
+			termList.setDestPortList(desSrcValue);
+			
+			String actionValue = "";
+			int actioncounter = 0;
+			if(termListDatas.getActionListDatas().size() > 0){
+				for(Object actionList : termListDatas.getActionListDatas()){
+					if(actionList instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) actionList).get("option").toString();
+						if(actioncounter>0){
+							actionValue = actionValue + ",";
+						}
+						actionValue = actionValue + key ;
+						actioncounter ++;
+					}
+				}
+			}
+			termList.setAction(actionValue);
+			
+			if(termList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(termList.getTermName(), "termName", TermList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					termList.setUserCreatedBy(this.getUserInfo(userId));
+					termList.setUserModifiedBy(this.getUserInfo(userId));
+					termListDao.Save(termList);
+				}
+			}else{
+				termList.setUserModifiedBy(this.getUserInfo(userId));
+				termListDao.update(termList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.termListDao.getTermListData());
+			}
+			JSONObject j = new JSONObject("{termListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_termList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeTermListDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			TermList termList = (TermList)mapper.readValue(root.get("data").toString(), TermList.class);
+			termListDao.delete(termList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.termListDao.getTermListData());
+			JSONObject j = new JSONObject("{termListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	//ParentList Dictionary Data
+	@RequestMapping(value={"/get_FWDictionaryListDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getFWDictListDictionaryEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("fwDictListDictionaryDatas", mapper.writeValueAsString(fwDictionaryListDao.getFWDictionaryListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_FWDictionaryListData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getFWDictionaryListEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("fwDictListDictionaryDatas", mapper.writeValueAsString(fwDictionaryListDao.getFWDictionaryListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/fw_dictionary/save_FWDictionaryList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveFWDictionaryList(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			FirewallDictionaryList fwDictList = (FirewallDictionaryList)mapper.readValue(root.get("fwDictListDictionaryData").toString(), FirewallDictionaryList.class);
+			GridData gridData = (GridData)mapper.readValue(root.get("fwDictListDictionaryData").toString(), GridData.class);
+			String userSLValue = "";
+			int slcounter = 0;
+			if(gridData.getAttributes().size() > 0){
+				for(Object attribute : gridData.getAttributes()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(slcounter>0){
+							userSLValue = userSLValue + ",";
+						}
+						userSLValue = userSLValue + key ;
+						slcounter ++;
+					}
+				}
+			}
+			fwDictList.setServiceList(userSLValue);
+			String userALValue = "";
+			int alcounter = 0;
+			if(gridData.getAlAttributes().size() > 0){
+				for(Object attribute : gridData.getAlAttributes()){
+					if(attribute instanceof LinkedHashMap<?, ?>){
+						String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
+						if(alcounter>0){
+							userALValue = userALValue + ",";
+						}
+						userALValue = userALValue + key ;
+						alcounter ++;
+					}
+				}
+			}
+			fwDictList.setAddressList(userALValue);
+			if(fwDictList.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(fwDictList.getParentItemName(), "parentItemName", FirewallDictionaryList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					fwDictionaryListDao.Save(fwDictList);
+				}
+			}else{
+				fwDictionaryListDao.update(fwDictList); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.fwDictionaryListDao.getFWDictionaryListData());
+			}
+			JSONObject j = new JSONObject("{fwDictListDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/fw_dictionary/remove_FWDictionaryList.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeFWDictionaryListy(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			FirewallDictionaryList fwDictList = (FirewallDictionaryList)mapper.readValue(root.get("data").toString(), FirewallDictionaryList.class);
+			fwDictionaryListDao.delete(fwDictList);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.fwDictionaryListDao.getFWDictionaryListData());
+			JSONObject j = new JSONObject("{fwDictListDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+}
+
+class AGGridData{
+	private ArrayList<Object> attributes;
+
+	public ArrayList<Object> getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(ArrayList<Object> attributes) {
+		this.attributes = attributes;
+	}
+}
+
+class TermListData{
+	private ArrayList<Object> fromZoneDatas;
+	private ArrayList<Object> toZoneDatas;
+	private ArrayList<Object> sourceListDatas;
+	private ArrayList<Object> destinationListDatas;
+	private ArrayList<Object> sourceServiceDatas;
+	private ArrayList<Object> destinationServiceDatas;
+	private ArrayList<Object> actionListDatas;
+	public ArrayList<Object> getFromZoneDatas() {
+		return fromZoneDatas;
+	}
+	public void setFromZoneDatas(ArrayList<Object> fromZoneDatas) {
+		this.fromZoneDatas = fromZoneDatas;
+	}
+	public ArrayList<Object> getToZoneDatas() {
+		return toZoneDatas;
+	}
+	public void setToZoneDatas(ArrayList<Object> toZoneDatas) {
+		this.toZoneDatas = toZoneDatas;
+	}
+	public ArrayList<Object> getSourceListDatas() {
+		return sourceListDatas;
+	}
+	public void setSourceListDatas(ArrayList<Object> sourceListDatas) {
+		this.sourceListDatas = sourceListDatas;
+	}
+	public ArrayList<Object> getDestinationListDatas() {
+		return destinationListDatas;
+	}
+	public void setDestinationListDatas(ArrayList<Object> destinationListDatas) {
+		this.destinationListDatas = destinationListDatas;
+	}
+	public ArrayList<Object> getSourceServiceDatas() {
+		return sourceServiceDatas;
+	}
+	public void setSourceServiceDatas(ArrayList<Object> sourceServiceDatas) {
+		this.sourceServiceDatas = sourceServiceDatas;
+	}
+	public ArrayList<Object> getDestinationServiceDatas() {
+		return destinationServiceDatas;
+	}
+	public void setDestinationServiceDatas(ArrayList<Object> destinationServiceDatas) {
+		this.destinationServiceDatas = destinationServiceDatas;
+	}
+	public ArrayList<Object> getActionListDatas() {
+		return actionListDatas;
+	}
+	public void setActionListDatas(ArrayList<Object> actionListDatas) {
+		this.actionListDatas = actionListDatas;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java
new file mode 100644
index 0000000..c3329db
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java
@@ -0,0 +1,718 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.DCAEUUIDDao;
+import org.openecomp.policy.rest.dao.MicroServiceConfigNameDao;
+import org.openecomp.policy.rest.dao.MicroServiceLocationDao;
+import org.openecomp.policy.rest.dao.MicroServiceModelsDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.DCAEuuid;
+import org.openecomp.policy.rest.jpa.MicroServiceConfigName;
+import org.openecomp.policy.rest.jpa.MicroServiceLocation;
+import org.openecomp.policy.rest.jpa.MicroServiceModels;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.openecomp.policy.rest.util.MSAttributeObject;
+import org.openecomp.policy.rest.util.MSModelUtitils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class MicroServiceDictionaryController {
+	private static final Log logger	= LogFactory.getLog(MicroServiceDictionaryController.class);
+
+	@Autowired
+	MicroServiceConfigNameDao microServiceConfigNameDao;
+	
+	@Autowired
+	MicroServiceLocationDao microServiceLocationDao;
+	
+	@Autowired
+	MicroServiceModelsDao microServiceModelsDao;
+	
+	@Autowired
+	DCAEUUIDDao dcaeUUIDDao;
+	
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+
+	private String newFile;
+	private String directory;
+	private List<String> dirDependencyList = new ArrayList<String>();
+	private HashMap<String,MSAttributeObject > classMap = new HashMap<String,MSAttributeObject>();
+	MSModelUtitils utils = new MSModelUtitils();
+	private MicroServiceModels newModel;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+	
+	@RequestMapping(value={"/get_DCAEUUIDDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getDCAEUUIDDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("dcaeUUIDDictionaryDatas", mapper.writeValueAsString(dcaeUUIDDao.getDCAEuuidDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+
+	@RequestMapping(value={"/get_DCAEUUIDData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getDCAEUUIDDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("dcaeUUIDDictionaryDatas", mapper.writeValueAsString(dcaeUUIDDao.getDCAEuuidData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ms_dictionary/save_dcaeUUID.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveDCAEUUIDDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DCAEuuid dCAEuuid = (DCAEuuid)mapper.readValue(root.get("dcaeUUIDDictionaryData").toString(), DCAEuuid.class);
+			if(dCAEuuid.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(dCAEuuid.getName(), "name", DCAEuuid.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					dcaeUUIDDao.Save(dCAEuuid);
+				}
+			}else{
+				dcaeUUIDDao.update(dCAEuuid); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.dcaeUUIDDao.getDCAEuuidData());
+			} 
+			JSONObject j = new JSONObject("{dcaeUUIDDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ms_dictionary/remove_dcaeuuid.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeDCAEUUIDDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			DCAEuuid dCAEuuid = (DCAEuuid)mapper.readValue(root.get("data").toString(), DCAEuuid.class);
+			dcaeUUIDDao.delete(dCAEuuid);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.dcaeUUIDDao.getDCAEuuidData());
+			JSONObject j = new JSONObject("{dcaeUUIDDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	
+	@RequestMapping(value={"/get_MicroServiceConfigNameDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceConfigNameByNameDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceCongigNameDictionaryDatas", mapper.writeValueAsString(microServiceConfigNameDao.getMSConfigDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	
+	
+	@RequestMapping(value={"/get_MicroServiceConfigNameData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceConfigNameDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceCongigNameDictionaryDatas", mapper.writeValueAsString(microServiceConfigNameDao.getMicroServiceConfigNameData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ms_dictionary/save_configName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveMicroServiceConfigNameDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceConfigName microServiceConfigName = (MicroServiceConfigName)mapper.readValue(root.get("microServiceCongigNameDictionaryData").toString(), MicroServiceConfigName.class);
+			if(microServiceConfigName.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(microServiceConfigName.getName(), "name", MicroServiceConfigName.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					microServiceConfigNameDao.Save(microServiceConfigName);
+				}
+			}else{
+				microServiceConfigNameDao.update(microServiceConfigName); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.microServiceConfigNameDao.getMicroServiceConfigNameData());
+			}
+			JSONObject j = new JSONObject("{microServiceCongigNameDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ms_dictionary/remove_msConfigName.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeMicroServiceConfigNameDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceConfigName microServiceConfigName = (MicroServiceConfigName)mapper.readValue(root.get("data").toString(), MicroServiceConfigName.class);
+			microServiceConfigNameDao.delete(microServiceConfigName);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.microServiceConfigNameDao.getMicroServiceConfigNameData());
+			JSONObject j = new JSONObject("{microServiceCongigNameDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_MicroServiceLocationDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceLocationByNameDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceLocationDictionaryDatas", mapper.writeValueAsString(microServiceLocationDao.getMSLocationDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_MicroServiceLocationData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceLocationDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceLocationDictionaryDatas", mapper.writeValueAsString(microServiceLocationDao.getMicroServiceLocationData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ms_dictionary/save_location.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveMicroServiceLocationDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceLocation microServiceLocation = (MicroServiceLocation)mapper.readValue(root.get("microServiceLocationDictionaryData").toString(), MicroServiceLocation.class);
+			if(microServiceLocation.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(microServiceLocation.getName(), "name", MicroServiceLocation.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					microServiceLocationDao.Save(microServiceLocation);
+				}
+			}else{
+				microServiceLocationDao.update(microServiceLocation); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.microServiceLocationDao.getMicroServiceLocationData());
+			}
+			JSONObject j = new JSONObject("{microServiceLocationDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ms_dictionary/remove_msLocation.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeMicroServiceLocationDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceLocation microServiceLocation = (MicroServiceLocation)mapper.readValue(root.get("data").toString(), MicroServiceLocation.class);
+			microServiceLocationDao.delete(microServiceLocation);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.microServiceLocationDao.getMicroServiceLocationData());
+			JSONObject j = new JSONObject("{microServiceLocationDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_MicroServiceModelsDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceModelsDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceModelsDictionaryDatas", mapper.writeValueAsString(microServiceModelsDao.getMSModelsDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_MicroServiceModelsData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceModelsDictionaryEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("microServiceModelsDictionaryDatas", mapper.writeValueAsString(microServiceModelsDao.getMicroServiceModelsData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ms_dictionary/save_model.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView saveMicroServiceModelsDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceModels microServiceModels = (MicroServiceModels)mapper.readValue(root.get("microServiceModelsDictionaryData").toString(), MicroServiceModels.class);
+			String userId = root.get("loginId").textValue();
+			microServiceModels.setAttributes(this.newModel.getAttributes());
+			microServiceModels.setRef_attributes(this.newModel.getRef_attributes());
+			microServiceModels.setDependency(this.newModel.getDependency());
+			microServiceModels.setModelName(this.newModel.getModelName());
+			microServiceModels.setSub_attributes(this.newModel.getSub_attributes());
+			microServiceModels.setVersion(this.newModel.getVersion());
+			if(microServiceModels.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(microServiceModels.getModelName(), "modelName", MicroServiceModels.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					microServiceModels.setUserCreatedBy(this.getUserInfo(userId));
+					microServiceModelsDao.Save(microServiceModels);
+				}
+			}else{
+				microServiceModelsDao.update(microServiceModels); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.microServiceModelsDao.getMicroServiceModelsData());
+			} 
+			JSONObject j = new JSONObject("{microServiceModelsDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ms_dictionary/remove_msModel.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removeMicroServiceModelsDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			MicroServiceModels microServiceModels = (MicroServiceModels)mapper.readValue(root.get("data").toString(), MicroServiceModels.class);
+			microServiceModelsDao.delete(microServiceModels);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.microServiceModelsDao.getMicroServiceModelsData());
+			JSONObject j = new JSONObject("{microServiceModelsDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/ms_dictionary/set_MSModelData.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public void SetRuleData(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
+		for (FileItem item : items) {
+			if(item.getName().endsWith(".zip")){
+				this.newModel = new MicroServiceModels();
+				try{
+					File file = new File(item.getName());
+					OutputStream outputStream = new FileOutputStream(file);
+					IOUtils.copy(item.getInputStream(), outputStream);
+					outputStream.close();
+					this.newFile = file.toString();
+					this.newModel.setModelName(this.newFile.toString().split("-v")[0]);
+					if (this.newFile.toString().contains("-v")){
+						this.newModel.setVersion(this.newFile.toString().split("-v")[1].replace(".zip", ""));
+					}
+				}catch(Exception e){
+					logger.error("Upload error : " + e);
+				}
+			}
+		}
+		extractFolder(this.newFile);
+		List<File> fileList = listModelFiles(this.directory);
+		
+		File folder = new File(this.directory);
+		File[] test = folder.listFiles();
+		
+		//Process Main Model file first
+		String ignoreFile = null;
+		for (File file : test) {
+			if(!file.isDirectory() && file.getName().endsWith(".xmi")){
+            	retreiveDependency(file.toString(), true);
+            	ignoreFile = file.toString();
+            }	
+		}
+		
+		for(File tempFile: fileList){
+			if (!tempFile.toString().contains(ignoreFile)){
+				retreiveDependency(tempFile.toString(), false);
+			}
+		}
+		
+		addValuesToNewModel();
+		
+		File deleteFile = new File(this.newFile);
+		deleteFile.delete();
+	}
+	
+	private void addValuesToNewModel() {
+		//Loop  through the classmap and pull out the required info for the new file.
+		MSAttributeObject mainClass  = null;
+		ArrayList<String> dependency = null;
+		String subAttribute = null;
+		
+		mainClass = classMap.get(this.newModel.getModelName());
+		
+		if (mainClass !=null){
+			String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
+			dependency = new ArrayList<String>(Arrays.asList(dependTemp.split(",")));	
+			dependency = getFullDependencyList(dependency);
+			for (String element : dependency){
+				MSAttributeObject temp = new MSAttributeObject();
+				temp = classMap.get(element);
+				if (temp!=null){
+					mainClass.addAllRefAttribute(temp.getRefAttribute());
+					mainClass.addAllAttribute(temp.getAttribute());
+				}
+			}
+			subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
+		}else{
+			subAttribute = "{}";
+			this.newModel.setDependency("");
+		}
+
+		if (mainClass.getDependency()==null){
+			mainClass.setDependency("");
+		}
+
+		this.newModel.setDependency(mainClass.getDependency());
+		this.newModel.setSub_attributes(subAttribute.toString());
+		this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
+		this.newModel.setRef_attributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
+	
+	} 
+	
+	private ArrayList<String> getFullDependencyList(ArrayList<String> dependency) {
+		ArrayList<String> returnList = new ArrayList<String>();
+		ArrayList<String> workingList = new ArrayList<String>();
+		returnList.addAll(dependency);
+		for (String element : dependency ){
+			if (classMap.containsKey(element)){
+				MSAttributeObject value = classMap.get(element);			
+				String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]{"[", "]"}, new String[]{"", ""});
+				workingList = new ArrayList<String>(Arrays.asList(rawValue.split(",")));	
+				for(String depend : workingList){
+					if (!returnList.contains(depend) && !depend.isEmpty()){
+						returnList.add(depend.trim());
+						//getFullDepedency(workingList)
+					}
+				}
+			}
+		}
+		
+		return returnList;
+	}
+
+	
+	/*
+	 * Unzip file and store in the model directory for processing
+	 */
+	@SuppressWarnings("rawtypes")
+	private void extractFolder(String zipFile )  {
+	    int BUFFER = 2048;
+	    File file = new File(zipFile);
+
+	    ZipFile zip;
+		try {
+			zip = new ZipFile(file);
+		    String newPath =  "model" + File.separator + zipFile.substring(0, zipFile.length() - 4);
+		    this.directory = "model" + File.separator + zipFile.substring(0, zipFile.length() - 4);
+		    new File(newPath).mkdir();
+		    Enumeration zipFileEntries = zip.entries();
+	
+		    // Process each entry
+		    while (zipFileEntries.hasMoreElements()){
+		        // grab a zip file entry
+		        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+		        String currentEntry = entry.getName();
+		        File destFile = new File("model" + File.separator + currentEntry);
+		        File destinationParent = destFile.getParentFile();
+		        
+		        destinationParent.mkdirs();
+	
+		        if (!entry.isDirectory()){
+		            BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
+		            int currentByte;
+		            byte data[] = new byte[BUFFER];
+		            FileOutputStream fos = new FileOutputStream(destFile);
+		            BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
+		            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
+		                dest.write(data, 0, currentByte);
+		            }
+		            dest.flush();
+		            dest.close();
+		            is.close();
+		        }
+	
+		        if (currentEntry.endsWith(".zip")){
+		            extractFolder(destFile.getAbsolutePath());
+		        }
+		    }
+	    } catch (IOException e) {
+			logger.error("Failed to unzip model file " + zipFile);
+		}
+	}
+	
+	private void retreiveDependency(String workingFile, Boolean modelClass) {
+		
+		MSModelUtitils utils = new MSModelUtitils();
+	    HashMap<String, MSAttributeObject> tempMap = new HashMap<String, MSAttributeObject>();
+	    
+	    tempMap = utils.processEpackage(workingFile);
+	    
+	    classMap.putAll(tempMap);
+	    System.out.println(tempMap);
+	    
+	    return;   	}
+		
+	private List<File> listModelFiles(String directoryName) {
+		File directory = new File(directoryName);
+		List<File> resultList = new ArrayList<File>();
+		File[] fList = directory.listFiles();
+		for (File file : fList) {
+			if (file.isFile()) {
+				resultList.add(file);
+			} else if (file.isDirectory()) {
+				dirDependencyList.add(file.getName());
+				resultList.addAll(listModelFiles(file.getAbsolutePath()));
+			}
+		}
+		return resultList;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/PolicyScopeDictionaryController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/PolicyScopeDictionaryController.java
new file mode 100644
index 0000000..b8803d7
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/PolicyScopeDictionaryController.java
@@ -0,0 +1,667 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.GroupPolicyScopeListDao;
+import org.openecomp.policy.rest.dao.PolicyScopeClosedLoopDao;
+import org.openecomp.policy.rest.dao.PolicyScopeResourceDao;
+import org.openecomp.policy.rest.dao.PolicyScopeServiceDao;
+import org.openecomp.policy.rest.dao.PolicyScopeTypeDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.GroupPolicyScopeList;
+import org.openecomp.policy.rest.jpa.PolicyScopeClosedLoop;
+import org.openecomp.policy.rest.jpa.PolicyScopeResource;
+import org.openecomp.policy.rest.jpa.PolicyScopeService;
+import org.openecomp.policy.rest.jpa.PolicyScopeType;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class PolicyScopeDictionaryController {
+
+	@Autowired
+	GroupPolicyScopeListDao groupPolicyScopeListDao;
+	
+	@Autowired
+	PolicyScopeClosedLoopDao  policyScopeClosedLoopDao;
+	
+	@Autowired
+	PolicyScopeResourceDao PolicyScopeResourceDao;
+	
+	@Autowired
+	PolicyScopeTypeDao policyScopeTypeDao;
+	
+	@Autowired
+	PolicyScopeServiceDao policyScopeServiceDao;
+	
+
+	@Autowired
+	UserInfoDao userInfoDao;
+	
+	public UserInfo getUserInfo(String loginId){
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;	
+	}
+	
+	@RequestMapping(value={"/get_GroupPolicyScopeDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getGroupPolicyScopeEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("groupPolicyScopeListDatas", mapper.writeValueAsString(groupPolicyScopeListDao.getGroupPolicyScopeListDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_GroupPolicyScopeData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getGroupPolicyScopeEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("groupPolicyScopeListDatas", mapper.writeValueAsString(groupPolicyScopeListDao.getGroupPolicyScopeListData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ps_dictionary/save_psGroupPolicyScope.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePSGroupScopeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			GroupPolicyScopeList ecompData = (GroupPolicyScopeList)mapper.readValue(root.get("groupPolicyScopeListData").toString(), GroupPolicyScopeList.class);
+			GroupPolicyScope groupData = null;
+			try{
+				 groupData = (GroupPolicyScope)mapper.readValue(root.get("groupPolicyScopeListData1").toString(), GroupPolicyScope.class);
+			}catch(Exception e){
+				groupData = new GroupPolicyScope();
+				groupData.setResource(root.get("groupPolicyScopeListData1").get("resource").toString().replace("\"", ""));
+				groupData.setClosedloop(root.get("groupPolicyScopeListData1").get("closedloop").toString().replace("\"", ""));
+				groupData.setService(root.get("groupPolicyScopeListData1").get("service").toString().replace("\"", ""));
+				groupData.setType(root.get("groupPolicyScopeListData1").get("type").toString().replace("\"", ""));
+			}
+			
+			ArrayList<String> valueList = new ArrayList<String>();
+			String list = null;
+			String resourceValue = groupData.getResource();
+			String typeValue = groupData.getType();
+			String serviceValue = groupData.getService();
+			String closedLoopValue = groupData.getClosedloop();
+			valueList.add("resource=" + resourceValue);
+			valueList.add("service=" + serviceValue);
+			valueList.add("type=" + typeValue);
+			valueList.add("closedLoopControlName="  + closedLoopValue);
+			list = StringUtils.replaceEach(valueList.toString(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
+			ecompData.setGroupList(list);
+			if(!ecompData.getGroupName().startsWith("PolicyScope")){
+				String name = "PolicyScope_" + ecompData.getGroupName();
+				ecompData.setGroupName(name);
+			}
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getGroupName(), "name", GroupPolicyScopeList.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					groupPolicyScopeListDao.Save(ecompData);
+				}
+			}else{
+				groupPolicyScopeListDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.groupPolicyScopeListDao.getGroupPolicyScopeListData());
+			}
+			JSONObject j = new JSONObject("{groupPolicyScopeListDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ps_dictionary/remove_GroupPolicyScope.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePSGroupScopeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			GroupPolicyScopeList ecompData = (GroupPolicyScopeList)mapper.readValue(root.get("data").toString(), GroupPolicyScopeList.class);
+			groupPolicyScopeListDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.groupPolicyScopeListDao.getGroupPolicyScopeListData());
+			JSONObject j = new JSONObject("{groupPolicyScopeListDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_PSClosedLoopDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSClosedLoopEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psClosedLoopDictionaryDatas", mapper.writeValueAsString(policyScopeClosedLoopDao.getPolicyScopeClosedLoopDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PSClosedLoopData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSClosedLoopEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psClosedLoopDictionaryDatas", mapper.writeValueAsString(policyScopeClosedLoopDao.getPolicyScopeClosedLoopData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ps_dictionary/save_psClosedLoop.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePSClosedLoopDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeClosedLoop ecompData = (PolicyScopeClosedLoop)mapper.readValue(root.get("psClosedLoopDictionaryData").toString(), PolicyScopeClosedLoop.class);
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getName(), "name", PolicyScopeClosedLoop.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					policyScopeClosedLoopDao.Save(ecompData);
+				}
+			}else{
+				policyScopeClosedLoopDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.policyScopeClosedLoopDao.getPolicyScopeClosedLoopData());
+			}	 
+			JSONObject j = new JSONObject("{psClosedLoopDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ps_dictionary/remove_PSClosedLoop.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePSClosedLoopDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeClosedLoop ecompData = (PolicyScopeClosedLoop)mapper.readValue(root.get("data").toString(), PolicyScopeClosedLoop.class);
+			policyScopeClosedLoopDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.policyScopeClosedLoopDao.getPolicyScopeClosedLoopData());
+			JSONObject j = new JSONObject("{psClosedLoopDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_PSServiceDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSServiceEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psServiceDictionaryDatas", mapper.writeValueAsString(policyScopeServiceDao.getPolicyScopeServiceDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PSServiceData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSServiceEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psServiceDictionaryDatas", mapper.writeValueAsString(policyScopeServiceDao.getPolicyScopeServiceData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ps_dictionary/save_psService.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePSServiceDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeService ecompData = (PolicyScopeService)mapper.readValue(root.get("psServiceDictionaryData").toString(), PolicyScopeService.class);
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getName(), "name", PolicyScopeService.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					policyScopeServiceDao.Save(ecompData);
+				}
+			}else{
+				policyScopeServiceDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.policyScopeServiceDao.getPolicyScopeServiceData());
+			}	
+			JSONObject j = new JSONObject("{psServiceDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ps_dictionary/remove_PSService.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePSServiceDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeService ecompData = (PolicyScopeService)mapper.readValue(root.get("data").toString(), PolicyScopeService.class);
+			policyScopeServiceDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.policyScopeServiceDao.getPolicyScopeServiceData());
+			JSONObject j = new JSONObject("{psServiceDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_PSTypeDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSTypeEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psTypeDictionaryDatas", mapper.writeValueAsString(policyScopeTypeDao.getPolicyScopeTypeDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PSTypeData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSTypeEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psTypeDictionaryDatas", mapper.writeValueAsString(policyScopeTypeDao.getPolicyScopeTypeData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ps_dictionary/save_psType.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePSTypeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeType ecompData = (PolicyScopeType)mapper.readValue(root.get("psTypeDictionaryData").toString(), PolicyScopeType.class);
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getName(), "name", PolicyScopeType.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					policyScopeTypeDao.Save(ecompData);
+				}
+			}else{
+				policyScopeTypeDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.policyScopeTypeDao.getPolicyScopeTypeData());
+			} 
+			JSONObject j = new JSONObject("{psTypeDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ps_dictionary/remove_PSType.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePSTypeDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeType ecompData = (PolicyScopeType)mapper.readValue(root.get("data").toString(), PolicyScopeType.class);
+			policyScopeTypeDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.policyScopeTypeDao.getPolicyScopeTypeData());
+			JSONObject j = new JSONObject("{psTypeDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+	
+	@RequestMapping(value={"/get_PSResourceDataByName"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSResourceEntityDataByName(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psResourceDictionaryDatas", mapper.writeValueAsString(PolicyScopeResourceDao.getPolicyScopeResourceDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/get_PSResourceData"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getPSResourceEntityData(HttpServletRequest request, HttpServletResponse response){
+		try{
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("psResourceDictionaryDatas", mapper.writeValueAsString(PolicyScopeResourceDao.getPolicyScopeResourceData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		}
+		catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+	
+	@RequestMapping(value={"/ps_dictionary/save_psResource.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView savePSResourceDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception{
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeResource ecompData = (PolicyScopeResource)mapper.readValue(root.get("psResourceDictionaryData").toString(), PolicyScopeResource.class);
+			if(ecompData.getId() == 0){
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(ecompData.getName(), "name", PolicyScopeResource.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					PolicyScopeResourceDao.Save(ecompData);
+				}
+			}else{
+				PolicyScopeResourceDao.update(ecompData); 
+			} 
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.PolicyScopeResourceDao.getPolicyScopeResourceData());
+			}	  
+			JSONObject j = new JSONObject("{psResourceDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/ps_dictionary/remove_PSResource.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView removePSResourceDictionary(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		try{
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			PolicyScopeResource ecompData = (PolicyScopeResource)mapper.readValue(root.get("data").toString(), PolicyScopeResource.class);
+			PolicyScopeResourceDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.PolicyScopeResourceDao.getPolicyScopeResourceData());
+			JSONObject j = new JSONObject("{psResourceDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		}
+		catch (Exception e){
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+}
+
+	class GroupPolicyScope{
+	String resource;
+	String type;
+	String service;
+	String closedloop;
+	public String getResource() {
+		return resource;
+	}
+	public void setResource(String resource) {
+		this.resource = resource;
+	}
+	public String getType() {
+		return type;
+	}
+	public void setType(String type) {
+		this.type = type;
+	}
+	public String getService() {
+		return service;
+	}
+	public void setService(String service) {
+		this.service = service;
+	}
+	public String getClosedloop() {
+		return closedloop;
+	}
+	public void setClosedloop(String closedloop) {
+		this.closedloop = closedloop;
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/SafePolicyController.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/SafePolicyController.java
new file mode 100644
index 0000000..5ee72f4
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/SafePolicyController.java
@@ -0,0 +1,319 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.controller;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONObject;
+import org.openecomp.policy.pap.xacml.rest.util.JsonMessage;
+import org.openecomp.policy.rest.dao.CategoryDao;
+import org.openecomp.policy.rest.dao.RiskTypeDao;
+import org.openecomp.policy.rest.dao.SafePolicyWarningDao;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.Category;
+import org.openecomp.policy.rest.jpa.RiskType;
+import org.openecomp.policy.rest.jpa.SafePolicyWarning;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Controller
+public class SafePolicyController {
+
+	private static final Log logger = LogFactory.getLog(SafePolicyController.class);
+
+	@Autowired
+	SafePolicyWarningDao safePolicyWarningDao;
+
+	@Autowired
+	RiskTypeDao riskTypeDao;
+
+	@Autowired
+	UserInfoDao userInfoDao;
+
+	@Autowired
+	CategoryDao categoryDao;
+	
+
+	public Category getCategory() {
+		for (int i = 0; i < categoryDao.getCategoryListData().size(); i++) {
+			Category value = categoryDao.getCategoryListData().get(i);
+			if (value.getShortName().equals("resource")) {
+				return value;
+			}
+		}
+		return null;
+	}
+
+	public UserInfo getUserInfo(String loginId) {
+		UserInfo name = userInfoDao.getUserInfoByLoginId(loginId);
+		return name;
+	}
+
+	// EcompName Dictionary
+	@RequestMapping(value = { "/get_RiskTypeDataByName" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.GET }, produces = MediaType.APPLICATION_JSON_VALUE)
+	public void getRiskTypeDictionaryByNameEntityData(HttpServletRequest request, HttpServletResponse response) {
+		logger.info("get_RiskTypeDataByName is called");
+		try {
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("riskTypeDictionaryDatas", mapper.writeValueAsString(riskTypeDao.getRiskTypeDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@RequestMapping(value = { "/get_RiskTypeData" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.GET }, produces = MediaType.APPLICATION_JSON_VALUE)
+	public void getEcompNameDictionaryEntityData(HttpServletRequest request, HttpServletResponse response) {
+		logger.info("get_RiskTypeData is called");
+		try {
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("riskTypeDictionaryDatas", mapper.writeValueAsString(riskTypeDao.getRiskName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		} catch (Exception e) {
+			e.printStackTrace();
+			logger.error("ERROR While callinge DAO: " + e.getMessage());
+		}
+	}
+
+	@RequestMapping(value = { "/sp_dictionary/save_riskType.htm" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.POST })
+	public ModelAndView saveRiskTypeDictionary(HttpServletRequest request, HttpServletResponse response)
+			throws Exception {
+		try {
+			boolean duplicateflag = false;
+			System.out.println("SafePolicyController:  saveRiskTypeDictionary() is called");
+			logger.debug("SafePolicyController:  saveRiskTypeDictionary() is called");
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			RiskType riskTypeData = (RiskType) mapper.readValue(root.get("riskTypeDictionaryData").toString(),
+					RiskType.class);
+			String userId = root.get("loginId").textValue();
+			System.out.println("the userId from the ecomp portal is: " + userId);
+			if (riskTypeData.getId() == 0) {
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(riskTypeData.getRiskName(), "name", RiskType.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					riskTypeData.setUserCreatedBy(getUserInfo(userId));
+					riskTypeData.setUserModifiedBy(getUserInfo(userId));
+					System.out.println(
+							"SafePolicyController:  got the user info now about to call Save() method on riskTypedao");
+					riskTypeDao.Save(riskTypeData);
+				}
+			} else {
+				riskTypeData.setUserModifiedBy(this.getUserInfo(userId));
+				riskTypeDao.update(riskTypeData);
+			}
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.riskTypeDao.getRiskName());
+			}
+			JSONObject j = new JSONObject("{riskTypeDictionaryDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		} catch (Exception e) {
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value = { "/sp_dictionary/remove_riskType.htm" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.POST })
+	public ModelAndView removeEcompDictionary(HttpServletRequest request, HttpServletResponse response)
+			throws Exception {
+		try {
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			RiskType ecompData = (RiskType) mapper.readValue(root.get("data").toString(), RiskType.class);
+			riskTypeDao.delete(ecompData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.riskTypeDao.getRiskName());
+			JSONObject j = new JSONObject("{riskTypeDictionaryDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		} catch (Exception e) {
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value = { "/get_SafePolicyWarningDataByName" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.GET }, produces = MediaType.APPLICATION_JSON_VALUE)
+	public void getSafePolicyWarningEntityDataByName(HttpServletRequest request, HttpServletResponse response) {
+		try {
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("safePolicyWarningDatas",
+					mapper.writeValueAsString(safePolicyWarningDao.getSafePolicyWarningDataByName()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@RequestMapping(value = { "/get_SafePolicyWarningData" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.GET }, produces = MediaType.APPLICATION_JSON_VALUE)
+	public void getSafePolicyWarningeEntityData(HttpServletRequest request, HttpServletResponse response) {
+		try {
+			Map<String, Object> model = new HashMap<String, Object>();
+			ObjectMapper mapper = new ObjectMapper();
+			model.put("safePolicyWarningDatas",
+					mapper.writeValueAsString(safePolicyWarningDao.getSafePolicyWarningData()));
+			JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model));
+			JSONObject j = new JSONObject(msg);
+			response.getWriter().write(j.toString());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@RequestMapping(value = { "/sp_dictionary/save_safePolicyWarning.htm" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.POST })
+	public ModelAndView saveSafePolicyWarningDictionary(HttpServletRequest request, HttpServletResponse response)
+			throws Exception {
+		try {
+			boolean duplicateflag = false;
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			SafePolicyWarning safePolicyWarning = (SafePolicyWarning) mapper
+					.readValue(root.get("safePolicyWarningData").toString(), SafePolicyWarning.class);
+
+			if (safePolicyWarning.getId() == 0) {
+				CheckDictionaryDuplicateEntries entry = new CheckDictionaryDuplicateEntries();
+				List<Object> duplicateData =  entry.CheckDuplicateEntry(safePolicyWarning.getName(), "name", SafePolicyWarning.class);
+				if(!duplicateData.isEmpty()){
+					duplicateflag = true;
+				}else{
+					safePolicyWarningDao.Save(safePolicyWarning);
+				}
+			} else {
+				safePolicyWarningDao.update(safePolicyWarning);
+			}
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+			String responseString = "";
+			if(duplicateflag){
+				responseString = "Duplicate";
+			}else{
+				responseString = mapper.writeValueAsString(this.safePolicyWarningDao.getSafePolicyWarningData());
+			}
+			JSONObject j = new JSONObject("{safePolicyWarningDatas: " + responseString + "}");
+
+			out.write(j.toString());
+
+			return null;
+		} catch (Exception e) {
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+	@RequestMapping(value = { "/sp_dictionary/remove_SafePolicyWarning.htm" }, method = {
+			org.springframework.web.bind.annotation.RequestMethod.POST })
+	public ModelAndView removeSafePolicyWarningDictionary(HttpServletRequest request, HttpServletResponse response)
+			throws Exception {
+		try {
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			SafePolicyWarning safePolicyWarningData = (SafePolicyWarning) mapper.readValue(root.get("data").toString(),
+					SafePolicyWarning.class);
+			safePolicyWarningDao.delete(safePolicyWarningData);
+			response.setCharacterEncoding("UTF-8");
+			response.setContentType("application / json");
+			request.setCharacterEncoding("UTF-8");
+
+			PrintWriter out = response.getWriter();
+
+			String responseString = mapper.writeValueAsString(this.safePolicyWarningDao.getSafePolicyWarningData());
+			JSONObject j = new JSONObject("{groupPolicyScopeListDatas: " + responseString + "}");
+			out.write(j.toString());
+
+			return null;
+		} catch (Exception e) {
+			System.out.println(e);
+			response.setCharacterEncoding("UTF-8");
+			request.setCharacterEncoding("UTF-8");
+			PrintWriter out = response.getWriter();
+			out.write(e.getMessage());
+		}
+		return null;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/package-info.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/package-info.java
new file mode 100644
index 0000000..df0e40a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/controller/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * 
+ */
+/**
+ *
+ */
+package org.openecomp.policy.pap.xacml.rest.controller;
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionListDaoImpl.java
new file mode 100644
index 0000000..ba6c2c4
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionListDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ActionListDao;
+import org.openecomp.policy.rest.jpa.ActionList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ActionListDao")
+public class ActionListDaoImpl implements ActionListDao{
+
+	private static final Log logger = LogFactory.getLog(ActionListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ActionList> getActionListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<ActionList> actionListData = null;
+		try {
+			Criteria cr = session.createCriteria(ActionList.class);
+			actionListData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ActionList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return actionListData;
+
+	}
+
+	@Override
+	public void Save(ActionList actionList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(actionList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ActionList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(ActionList actionList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(actionList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ActionList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ActionList actionList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(actionList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ActionList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getActionListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+		try {
+			Criteria cr = session.createCriteria(ActionList.class);
+			List<ActionList> actionListData = cr.list();
+			for(int i = 0; i < actionListData.size(); i++){
+				data.add(actionListData.get(i).getActionName());
+			}
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ActionList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionPolicyDictDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionPolicyDictDaoImpl.java
new file mode 100644
index 0000000..50d41fd
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ActionPolicyDictDaoImpl.java
@@ -0,0 +1,185 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ActionPolicyDictDao;
+import org.openecomp.policy.rest.jpa.ActionPolicyDict;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+
+@Service("ActionPolicyDictDao")
+public class ActionPolicyDictDaoImpl implements ActionPolicyDictDao {
+	private static final Log logger = LogFactory.getLog(ActionPolicyDictDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ActionPolicyDict> getActionDictData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		
+        List<ActionPolicyDict> actionDictData = null;
+        try {
+        	Criteria cr = session.createCriteria(ActionPolicyDict.class);
+        	actionDictData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ActionDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return actionDictData;
+	}
+
+	@Override
+	public void Save(ActionPolicyDict action) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(action);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ActionDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void delete(ActionPolicyDict action) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(action);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ActionDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ActionPolicyDict action) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(action);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ActionDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getActionDictDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+		try {
+			Criteria cr = session.createCriteria(ActionPolicyDict.class);
+			List<ActionPolicyDict> attributeData = cr.list();  
+			for(int i = 0; i < attributeData.size(); i++){
+				data.add(attributeData.get(i).getAttributeName());
+			}	
+			tx.commit();			
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ActionDictionary Table"+e);			
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public ActionPolicyDict getActionEntityDatabyId(String action) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		ActionPolicyDict data = null;
+		try {
+			Criteria cr = session.createCriteria(ActionPolicyDict.class);	
+			List<ActionPolicyDict> attributeData = cr.add(Restrictions.eq("attributeName", action)).list();
+			for(Object entity : attributeData){
+				data = (ActionPolicyDict) entity;
+			}		
+			tx.commit();			
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ActionDictionary Table"+e);		
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AddressGroupDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AddressGroupDaoImpl.java
new file mode 100644
index 0000000..951a38a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AddressGroupDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.AddressGroupDao;
+import org.openecomp.policy.rest.jpa.AddressGroup;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("AddressGroupDao")
+public class AddressGroupDaoImpl implements AddressGroupDao{
+	private static final Log logger = LogFactory.getLog(AddressGroupDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<AddressGroup> getAddressGroupData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<AddressGroup> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(AddressGroup.class);
+			attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying AddressGroup Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(AddressGroup attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving AddressGroup Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(AddressGroup attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting AddressGroup Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(AddressGroup attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating AddressGroup Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getAddressGroupDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();   
+        try {
+        	Criteria cr = session.createCriteria(AddressGroup.class);
+        	 List<AddressGroup> attributeData = cr.list();
+        	 for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getGroupName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying AddressGroup Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AttributeDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AttributeDaoImpl.java
new file mode 100644
index 0000000..7eb51d3
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/AttributeDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.AttributeDao;
+import org.openecomp.policy.rest.jpa.Attribute;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("AttributeDao")
+public class AttributeDaoImpl implements AttributeDao {
+	private static final Log logger = LogFactory.getLog(AttributeDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<Attribute> getData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<Attribute> attributeData = null;
+		try {
+			Criteria cr = session.createCriteria(Attribute.class);
+			attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(Attribute attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(Attribute attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(Attribute attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getAttributeData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+		try {
+			Criteria cr = session.createCriteria(Attribute.class);
+			List<Attribute> attributeData = cr.list();
+			for(int i = 0; i < attributeData.size(); i++){
+				data.add(attributeData.get(i).getXacmlId());
+			}
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/BRMSParamTemplateDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/BRMSParamTemplateDaoImpl.java
new file mode 100644
index 0000000..4f8478d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/BRMSParamTemplateDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.BRMSParamTemplateDao;
+import org.openecomp.policy.rest.jpa.BRMSParamTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("BRMSParamTemplateDao")
+public class BRMSParamTemplateDaoImpl implements BRMSParamTemplateDao{
+	private static final Log logger = LogFactory.getLog(BRMSParamTemplateDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<BRMSParamTemplate> getBRMSParamTemplateData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+        List<BRMSParamTemplate> attributeData =null;
+        try {
+			Criteria cr = session.createCriteria(BRMSParamTemplate.class);
+			attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying BRMSParamTemplate Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(BRMSParamTemplate attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving BRMSParamTemplate Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(BRMSParamTemplate attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting BRMSParamTemplate Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(BRMSParamTemplate attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating BRMSParamTemplate Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getBRMSParamDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();     
+		List<String> data = new ArrayList<String>();  
+		try {
+			Criteria cr = session.createCriteria(BRMSParamTemplate.class);
+			List<BRMSParamTemplate> attributeData = cr.list();
+			for(int i = 0; i < attributeData.size(); i++){
+				data.add(attributeData.get(i).getRuleName());
+			}
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying BRMSParamTemplate Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/CategoryDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/CategoryDaoImpl.java
new file mode 100644
index 0000000..f3fcbf1
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/CategoryDaoImpl.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.CategoryDao;
+import org.openecomp.policy.rest.jpa.Category;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("CategoryDao")
+public class CategoryDaoImpl implements CategoryDao {
+	private static final Log logger = LogFactory.getLog(CategoryDaoImpl.class);
+
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<Category> getCategoryListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();		
+		List<Category> categoryListData = null;
+		try {
+			Criteria cr = session.createCriteria(Category.class);
+			categoryListData = cr.list();	
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying Category Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return categoryListData;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DCAEUUIDDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DCAEUUIDDaoImpl.java
new file mode 100644
index 0000000..ddd4606
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DCAEUUIDDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.DCAEUUIDDao;
+import org.openecomp.policy.rest.jpa.DCAEuuid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("DCAEUUIDDao")
+public class DCAEUUIDDaoImpl implements DCAEUUIDDao{
+	private static final Log logger = LogFactory.getLog(DCAEUUIDDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<DCAEuuid> getDCAEuuidData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<DCAEuuid> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(DCAEuuid.class);
+			attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DCAEUUID Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(DCAEuuid attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving DCAEUUID Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(DCAEuuid attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting DCAEUUID Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(DCAEuuid attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating DCAEUUID Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getDCAEuuidDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();  
+        List<String> data = new ArrayList<String>(); 
+        try {
+        	Criteria cr = session.createCriteria(DCAEuuid.class);
+        	 List<DCAEuuid> attributeData = cr.list();
+        	 for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DCAEUUID Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DecisionPolicyDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DecisionPolicyDaoImpl.java
new file mode 100644
index 0000000..9762e1d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DecisionPolicyDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.DecisionPolicyDao;
+import org.openecomp.policy.rest.jpa.DecisionSettings;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("DecisionSettingsDao")
+public class DecisionPolicyDaoImpl implements DecisionPolicyDao{
+	private static final Log logger = LogFactory.getLog(DecisionPolicyDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<DecisionSettings> getDecisionSettingsData() {
+			Session session = HibernateSession.getSessionFactory();
+			Transaction tx = session.beginTransaction();	
+	        List<DecisionSettings> decisionSettingsData = null;
+	        try {
+	        	Criteria cr = session.createCriteria(DecisionSettings.class);
+	        	decisionSettingsData = cr.list();
+				tx.commit();
+			} catch (Exception e) {
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DecisionSettings Table"+e);	
+			}finally{
+				try{
+					session.close();
+				}catch(Exception e1){
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+				}
+			}
+			return decisionSettingsData;
+			
+		}
+
+		@Override
+		public void Save(DecisionSettings decisionSettings) {
+			Session session = HibernateSession.getSessionFactory();
+			Transaction tx = session.beginTransaction();
+			try {
+				session.persist(decisionSettings);
+				tx.commit();	
+			}catch(Exception e){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving DecisionSettings Table"+e);	
+			}finally{
+				try{
+					session.close();
+				}catch(Exception e1){
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+				}
+			}
+			
+		}
+
+		@Override
+		public void delete(DecisionSettings decisionSettings) {
+			Session session = HibernateSession.getSessionFactory();
+			Transaction tx = session.beginTransaction();
+			try {
+				session.delete(decisionSettings);
+				tx.commit();	
+			}catch(Exception e){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting DecisionSettings Table"+e);	
+			}finally{
+				try{
+					session.close();
+				}catch(Exception e1){
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+				}
+			}
+		}
+
+		@Override
+		public void update(DecisionSettings decisionSettings) {
+			Session session = HibernateSession.getSessionFactory();
+			Transaction tx = session.beginTransaction();
+			try {
+				session.update(decisionSettings);
+				tx.commit();	
+			}catch(Exception e){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating DecisionSettings Table"+e);	
+			}finally{
+				try{
+					session.close();
+				}catch(Exception e1){
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+				}
+			}
+		}
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public List<String> getDecisionDataByName() {
+			Session session = HibernateSession.getSessionFactory();
+			Transaction tx = session.beginTransaction();		
+			List<String> data = new ArrayList<String>();
+			try {
+				Criteria cr = session.createCriteria(DecisionSettings.class);
+				List<DecisionSettings> decisionSettingsData = cr.list();
+				for(int i = 0; i < decisionSettingsData.size(); i++){
+					data.add(decisionSettingsData.get(i).getXacmlId());
+				}
+				tx.commit();
+			} catch (Exception e) {
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DecisionSettings Table"+e);	
+			}finally{
+				try{
+					session.close();
+				}catch(Exception e1){
+					logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+				}
+			}
+			return data;
+		}
+
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DescriptiveScopeDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DescriptiveScopeDaoImpl.java
new file mode 100644
index 0000000..8d28685
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/DescriptiveScopeDaoImpl.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.DescriptiveScopeDao;
+import org.openecomp.policy.rest.jpa.DescriptiveScope;
+import org.openecomp.policy.rest.jpa.PolicyVersion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("DescriptiveScopeDao")
+public class DescriptiveScopeDaoImpl implements DescriptiveScopeDao{
+	private static final Log logger = LogFactory.getLog(DescriptiveScopeDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<DescriptiveScope> getDescriptiveScope() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+        List<DescriptiveScope> descriptiveScopeData = null;
+        try {
+        	Criteria cr = session.createCriteria(DescriptiveScope.class);
+        	descriptiveScopeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return descriptiveScopeData;
+	}
+
+	@Override
+	public void Save(DescriptiveScope descriptiveScope) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(descriptiveScope);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(DescriptiveScope descriptiveScope) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(descriptiveScope);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(DescriptiveScope descriptiveScope) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(descriptiveScope);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getDescriptiveScopeDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<String> data = new ArrayList<String>();  
+    	try {
+    		Criteria cr = session.createCriteria(DescriptiveScope.class);
+            List<DescriptiveScope> descriptiveScopeData = cr.list();
+            for(int i = 0; i < descriptiveScopeData.size(); i++){
+           	 data.add(descriptiveScopeData.get(i).getScopeName());
+           }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public DescriptiveScope getDescriptiveScopeById(String name) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		DescriptiveScope data = null;
+		try {
+			Criteria cr = session.createCriteria(DescriptiveScope.class);
+			cr.add(Restrictions.eq("scopename",name));
+			data = (DescriptiveScope) cr.list().get(0);
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying DescriptiveScope Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EcompNameDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EcompNameDaoImpl.java
new file mode 100644
index 0000000..9bafc3a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EcompNameDaoImpl.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.EcompNameDao;
+import org.openecomp.policy.rest.jpa.EcompName;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("EcompNameDao")
+public class EcompNameDaoImpl implements EcompNameDao {
+	private static final Log logger = LogFactory.getLog(EcompNameDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<EcompName> getEcompName() {
+		System.out.println("EcompNameDaoImpl:  getEcompName() is called");
+		logger.debug("EcompNameDaoImpl:  getEcompName() is called");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<EcompName> ecompNameData = null;
+        try {
+        	Criteria cr = session.createCriteria(EcompName.class);
+			ecompNameData = cr.list();
+			System.out.println("Data returned from ecompname table"+ecompNameData.toString());
+			logger.debug("Data returned from ecompname table:  " + ecompNameData.toString());
+			tx.commit();
+		} catch (Exception e) {
+			System.out.println("Exception Occured while Querying ecompname"+e);
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying EcompName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return ecompNameData;
+	}
+
+	@Override
+	public void Save(EcompName ecompName) {
+		System.out.println("EcompNameDaoImpl:  Save() is called");
+		logger.debug("EcompNameDaoImpl:  Save() is called");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(ecompName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving EcompName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(EcompName ecompName) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(ecompName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting EcompName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(EcompName ecompName) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(ecompName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating EcompName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getEcompNameDataByName() {
+		logger.info("getEcompNameDataByName is call from the DAO implementation class.");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<String> data = new ArrayList<String>();    
+        try {
+        	Criteria cr = session.createCriteria(EcompName.class);
+            List<EcompName> ecompNameData = cr.list();
+            for(int i = 0; i < ecompNameData.size(); i++){
+           	 data.add(ecompNameData.get(i).getEcompName());
+           }
+            logger.info("data retrieved: " + data.toString());
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying EcompName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EnforcerPolicyDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EnforcerPolicyDaoImpl.java
new file mode 100644
index 0000000..ba621ab
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/EnforcerPolicyDaoImpl.java
@@ -0,0 +1,132 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.EnforcerPolicyDao;
+import org.openecomp.policy.rest.jpa.EnforcingType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("EnforcerPolicyDao")
+public class EnforcerPolicyDaoImpl implements EnforcerPolicyDao {
+	private static final Log logger = LogFactory.getLog(EnforcerPolicyDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<EnforcingType> getEnforcingTypeData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<EnforcingType> enforcingTypeData = null;
+        try {
+        	Criteria cr = session.createCriteria(EnforcingType.class);
+            enforcingTypeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying EnforcingType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return enforcingTypeData;
+		
+	}
+
+	@Override
+	public void Save(EnforcingType enforcingType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(enforcingType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving EnforcingType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(EnforcingType enforcingType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(enforcingType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting EnforcingType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(EnforcingType enforcingType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(enforcingType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating EnforcingType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/FirewallDictionaryListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/FirewallDictionaryListDaoImpl.java
new file mode 100644
index 0000000..b19a58b
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/FirewallDictionaryListDaoImpl.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.FirewallDictionaryListDao;
+import org.openecomp.policy.rest.jpa.FirewallDictionaryList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+@Service("FirewallDictionaryListDao")
+public class FirewallDictionaryListDaoImpl implements FirewallDictionaryListDao {
+	private static final Log logger = LogFactory.getLog(FirewallDictionaryListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@Override
+	public List<FirewallDictionaryList> getFWDictionaryListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<FirewallDictionaryList> attributeData =  null;
+        try {
+        	Criteria cr = session.createCriteria(FirewallDictionaryList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+
+	}
+
+	@Override
+	public List<String> getFWDictionaryListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(FirewallDictionaryList.class);
+            List<FirewallDictionaryList> attributeData = cr.list();    
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getParentItemName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(FirewallDictionaryList firewallDictionaryList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(firewallDictionaryList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(FirewallDictionaryList firewallDictionaryList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(firewallDictionaryList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(FirewallDictionaryList firewallDictionaryList) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(firewallDictionaryList);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void updateQuery(String query) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+		try {
+			Query hbquery = session.createQuery(query);
+			hbquery.executeUpdate();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public FirewallDictionaryList getFWDictionaryDataById(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		FirewallDictionaryList data = null;
+        try {
+        	Criteria cr = session.createCriteria(FirewallDictionaryList.class);
+        	cr = cr.add(Restrictions.eq("parentItemName",value));
+        	data = (FirewallDictionaryList) cr.list().get(0);
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying FirewallDictionaryList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/GroupPolicyScopeListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/GroupPolicyScopeListDaoImpl.java
new file mode 100644
index 0000000..edc147f
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/GroupPolicyScopeListDaoImpl.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.GroupPolicyScopeListDao;
+import org.openecomp.policy.rest.jpa.GroupPolicyScopeList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("GroupPolicyScopeListDao")
+public class GroupPolicyScopeListDaoImpl implements GroupPolicyScopeListDao {
+	private static final Log logger = LogFactory.getLog(GroupPolicyScopeListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<GroupPolicyScopeList> getGroupPolicyScopeListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		 List<GroupPolicyScopeList> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(GroupPolicyScopeList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying GroupPolicyScopeList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getGroupPolicyScopeListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+		try {
+			Criteria cr = session.createCriteria(GroupPolicyScopeList.class);
+			List<GroupPolicyScopeList> attributeData = cr.list();           
+			for(int i = 0; i < attributeData.size(); i++){
+				data.add(attributeData.get(i).getGroupName());
+			}
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying GroupPolicyScopeList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(GroupPolicyScopeList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving GroupPolicyScopeList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(GroupPolicyScopeList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(GroupPolicyScopeList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<GroupPolicyScopeList> CheckDuplicateEntry(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<GroupPolicyScopeList> data = null;
+		try {
+			Criteria cr = session.createCriteria(GroupPolicyScopeList.class);
+			cr.add(Restrictions.eq("name",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying GroupPolicyScopeList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceConfigNameDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceConfigNameDaoImpl.java
new file mode 100644
index 0000000..fdee32c
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceConfigNameDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.MicroServiceConfigNameDao;
+import org.openecomp.policy.rest.jpa.MicroServiceConfigName;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("MicroServiceConfigNameDao")
+public class MicroServiceConfigNameDaoImpl implements MicroServiceConfigNameDao{
+	private static final Log logger = LogFactory.getLog(MicroServiceConfigNameDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<MicroServiceConfigName> getMicroServiceConfigNameData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		 List<MicroServiceConfigName> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceConfigName.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceConfigName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(MicroServiceConfigName attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving MicroServiceConfigName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(MicroServiceConfigName attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting MicroServiceConfigName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(MicroServiceConfigName attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating MicroServiceConfigName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getMSConfigDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceConfigName.class);
+            List<MicroServiceConfigName> attributeData = cr.list();            
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceConfigName Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceLocationDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceLocationDaoImpl.java
new file mode 100644
index 0000000..91a2f42
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceLocationDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.MicroServiceLocationDao;
+import org.openecomp.policy.rest.jpa.MicroServiceLocation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("MicroServiceLocationDao")
+public class MicroServiceLocationDaoImpl implements MicroServiceLocationDao{
+	private static final Log logger = LogFactory.getLog(MicroServiceLocationDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<MicroServiceLocation> getMicroServiceLocationData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<MicroServiceLocation> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceLocation.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceLocation Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(MicroServiceLocation attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving MicroServiceLocation Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(MicroServiceLocation attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting MicroServiceLocation Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(MicroServiceLocation attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating MicroServiceLocation Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getMSLocationDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceLocation.class);
+            List<MicroServiceLocation> attributeData = cr.list();
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceLocation Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceModelsDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceModelsDaoImpl.java
new file mode 100644
index 0000000..c4e66b5
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/MicroServiceModelsDaoImpl.java
@@ -0,0 +1,161 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.MicroServiceModelsDao;
+import org.openecomp.policy.rest.jpa.MicroServiceModels;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("MicroServiceModelsDao")
+public class MicroServiceModelsDaoImpl implements MicroServiceModelsDao{
+	private static final Log logger = LogFactory.getLog(MicroServiceModelsDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<MicroServiceModels> getMicroServiceModelsData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<MicroServiceModels> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceModels.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceModels Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(MicroServiceModels attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving MicroServiceModels Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(MicroServiceModels attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting MicroServiceModels Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(MicroServiceModels attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating MicroServiceModels Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getMSModelsDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(MicroServiceModels.class);
+            List<MicroServiceModels> attributeData = cr.list();         
+            for(int i = 0; i < attributeData.size(); i++){
+            	if(attributeData.get(i).getVersion() == null || attributeData.get(i).getVersion().equals("")){
+            		data.add(attributeData.get(i).getModelName());
+            	}else{
+            		data.add(attributeData.get(i).getModelName() + "-v" + attributeData.get(i).getVersion());
+            	}
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying MicroServiceModels Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PEPOptionsDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PEPOptionsDaoImpl.java
new file mode 100644
index 0000000..92b89e9
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PEPOptionsDaoImpl.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PEPOptionsDao;
+import org.openecomp.policy.rest.jpa.PEPOptions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PEPOptionsDao")
+public class PEPOptionsDaoImpl implements PEPOptionsDao{
+	private static final Log logger = LogFactory.getLog(PEPOptionsDaoImpl.class);
+
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PEPOptions> getPEPOptionsData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PEPOptions> pepOptionsData = null;
+        try {
+        	Criteria cr = session.createCriteria(PEPOptions.class);
+            pepOptionsData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PEPOptions Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return pepOptionsData;
+		
+	}
+
+	@Override
+	public void Save(PEPOptions pepOptions) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(pepOptions);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PEPOptions Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PEPOptions pepOptions) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(pepOptions);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PEPOptions Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(PEPOptions pepOptions) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(pepOptions);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PEPOptions Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPEPOptionsDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PEPOptions.class);
+            List<PEPOptions> pepOptionsData = cr.list();  
+            for(int i = 0; i < pepOptionsData.size(); i++){
+            	 data.add(pepOptionsData.get(i).getPepName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PEPOptions Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeClosedLoopDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeClosedLoopDaoImpl.java
new file mode 100644
index 0000000..6ac3e5b
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeClosedLoopDaoImpl.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PolicyScopeClosedLoopDao;
+import org.openecomp.policy.rest.jpa.PolicyScopeClosedLoop;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PolicyScopeClosedLoopDao")
+public class PolicyScopeClosedLoopDaoImpl implements PolicyScopeClosedLoopDao{
+	private static final Log logger = LogFactory.getLog(PolicyScopeClosedLoopDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeClosedLoop> getPolicyScopeClosedLoopData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeClosedLoop> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeClosedLoop.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPolicyScopeClosedLoopDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeClosedLoop.class);
+            List<PolicyScopeClosedLoop> attributeData = cr.list();            
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(PolicyScopeClosedLoop attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PolicyScopeClosedLoop attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(PolicyScopeClosedLoop attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeClosedLoop> CheckDuplicateEntry(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeClosedLoop> data = null;
+		try {
+			Criteria cr = session.createCriteria(PolicyScopeClosedLoop.class);
+			cr.add(Restrictions.eq("name",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeClosedLoop Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeResourceDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeResourceDaoImpl.java
new file mode 100644
index 0000000..6fe91b1
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeResourceDaoImpl.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PolicyScopeResourceDao;
+import org.openecomp.policy.rest.jpa.PolicyScopeResource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PolicyScopeResourceDao")
+public class PolicyScopeResourceDaoImpl implements PolicyScopeResourceDao{
+	private static final Log logger = LogFactory.getLog(PolicyScopeResourceDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeResource> getPolicyScopeResourceData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeResource> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeResource.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPolicyScopeResourceDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeResource.class);
+            List<PolicyScopeResource> attributeData = cr.list();     
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(PolicyScopeResource attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void delete(PolicyScopeResource attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(PolicyScopeResource attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeResource> CheckDuplicateEntry(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeResource> data = null;
+		try {
+			Criteria cr = session.createCriteria(PolicyScopeResource.class);
+			cr.add(Restrictions.eq("name",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeResource Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+  
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeServiceDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeServiceDaoImpl.java
new file mode 100644
index 0000000..d90d5a0
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeServiceDaoImpl.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PolicyScopeServiceDao;
+import org.openecomp.policy.rest.jpa.PolicyScopeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PolicyScopeServiceDao")
+public class PolicyScopeServiceDaoImpl implements PolicyScopeServiceDao{
+	private static final Log logger = LogFactory.getLog(PolicyScopeServiceDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeService> getPolicyScopeServiceData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeService> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeService.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPolicyScopeServiceDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeService.class);
+            List<PolicyScopeService> attributeData = cr.list();     
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(PolicyScopeService attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PolicyScopeService attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(PolicyScopeService attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeService> CheckDuplicateEntry(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeService> data = null;
+		try {
+			Criteria cr = session.createCriteria(PolicyScopeService.class);
+			cr.add(Restrictions.eq("name",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeService Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeTypeDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeTypeDaoImpl.java
new file mode 100644
index 0000000..66317a4
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PolicyScopeTypeDaoImpl.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PolicyScopeTypeDao;
+import org.openecomp.policy.rest.jpa.PolicyScopeType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PolicyScopeTypeDao")
+public class PolicyScopeTypeDaoImpl implements  PolicyScopeTypeDao{
+	private static final Log logger = LogFactory.getLog(PolicyScopeTypeDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeType> getPolicyScopeTypeData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeType> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeType.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPolicyScopeTypeDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PolicyScopeType.class);
+            List<PolicyScopeType> attributeData = cr.list();     
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(PolicyScopeType attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PolicyScopeType attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(PolicyScopeType attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PolicyScopeType> CheckDuplicateEntry(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PolicyScopeType> data = null;
+		try {
+			Criteria cr = session.createCriteria(PolicyScopeType.class);
+			cr.add(Restrictions.eq("name",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PolicyScopeType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PortListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PortListDaoImpl.java
new file mode 100644
index 0000000..a3139b2
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PortListDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PortListDao;
+import org.openecomp.policy.rest.jpa.PortList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PortListDao")
+public class PortListDaoImpl implements PortListDao {
+	private static final Log logger = LogFactory.getLog(PortListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PortList> getPortListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PortList> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PortList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PortList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(PortList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PortList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PortList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PortList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(PortList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PortList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPortListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PortList.class);
+            List<PortList> attributeData = cr.list();      
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getPortName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PortList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PrefixListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PrefixListDaoImpl.java
new file mode 100644
index 0000000..2fecc7d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/PrefixListDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.PrefixListDao;
+import org.openecomp.policy.rest.jpa.PREFIXLIST;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("PrefixListDao")
+public class PrefixListDaoImpl implements PrefixListDao{
+	private static final Log logger = LogFactory.getLog(PrefixListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<PREFIXLIST> getPREFIXLISTData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<PREFIXLIST> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(PREFIXLIST.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PREFIXLIST Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(PREFIXLIST attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving PREFIXLIST Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(PREFIXLIST attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting PREFIXLIST Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(PREFIXLIST attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating PREFIXLIST Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getPrefixListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(PREFIXLIST.class);
+            List<PREFIXLIST> attributeData = cr.list();    
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getPrefixListName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying PREFIXLIST Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ProtocolListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ProtocolListDaoImpl.java
new file mode 100644
index 0000000..7d78d38
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ProtocolListDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ProtocolListDao;
+import org.openecomp.policy.rest.jpa.ProtocolList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ProtocolListDao")
+public class ProtocolListDaoImpl implements ProtocolListDao {
+	private static final Log logger = LogFactory.getLog(ProtocolListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ProtocolList> getProtocolListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<ProtocolList> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(ProtocolList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ProtocolList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(ProtocolList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ProtocolList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(ProtocolList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ProtocolList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ProtocolList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ProtocolList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getProtocolListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(ProtocolList.class);
+            List<ProtocolList> attributeData = cr.list();     
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getProtocolName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ProtocolList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/RiskTypeDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/RiskTypeDaoImpl.java
new file mode 100644
index 0000000..1318f82
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/RiskTypeDaoImpl.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.EcompNameDao;
+import org.openecomp.policy.rest.dao.RiskTypeDao;
+import org.openecomp.policy.rest.jpa.EcompName;
+import org.openecomp.policy.rest.jpa.RiskType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("RiskTypeDao")
+public class RiskTypeDaoImpl implements RiskTypeDao {
+	private static final Log logger = LogFactory.getLog(RiskTypeDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<RiskType> getRiskName() {
+		System.out.println("RiskTypeDaoImpl:  getRiskName() is called");
+		logger.debug("RiskTypeDaoImpl:  getRiskName() is called");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<RiskType> riskTypeData = null;
+        try {
+        	Criteria cr = session.createCriteria(RiskType.class);
+        	riskTypeData = cr.list();
+			logger.debug("Data returned from RiskType table:  " + riskTypeData.toString());
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying RiskType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return riskTypeData;
+	}
+
+	@Override
+	public void Save(RiskType riskName) {
+		System.out.println("RiskTypeDaoImpl:  Save() is called");
+		logger.debug("RiskTypeDaoImpl:  Save() is called");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(riskName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving RiskType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(RiskType riskName) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(riskName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting RiskType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(RiskType riskName) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(riskName);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating RiskType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getRiskTypeDataByName() {
+		logger.info("getRiskTypeDataByName is call from the DAO implementation class.");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();	
+        List<String> data = new ArrayList<String>();    
+        try {
+        	Criteria cr = session.createCriteria(RiskType.class);
+            List<RiskType> riskTypeData = cr.list();
+            for(int i = 0; i < riskTypeData.size(); i++){
+           	 data.add(riskTypeData.get(i).getRiskName());
+           }
+            logger.info("data retrieved: " + data.toString());
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying RiskType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SafePolicyWarningDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SafePolicyWarningDaoImpl.java
new file mode 100644
index 0000000..37a77f9
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SafePolicyWarningDaoImpl.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.SafePolicyWarningDao;
+import org.openecomp.policy.rest.jpa.SafePolicyWarning;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("SafePolicyWarningDao")
+public class SafePolicyWarningDaoImpl implements SafePolicyWarningDao {
+	private static final Log logger = LogFactory.getLog(SafePolicyWarningDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<SafePolicyWarning> getSafePolicyWarningData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		 List<SafePolicyWarning> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(SafePolicyWarning.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying SafePolicyWarning Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getSafePolicyWarningDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+		try {
+			Criteria cr = session.createCriteria(SafePolicyWarning.class);
+			List<SafePolicyWarning> attributeData = cr.list();           
+			for(int i = 0; i < attributeData.size(); i++){
+				data.add(attributeData.get(i).getName());
+			}
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying SafePolicyWarning Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public void Save(SafePolicyWarning attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving SafePolicyWarning Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(SafePolicyWarning attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void update(SafePolicyWarning attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating Attribute Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public SafePolicyWarning getSafePolicyWarningDataById(String riskType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		SafePolicyWarning data = null;
+		try {
+		Criteria cr = session.createCriteria(SafePolicyWarning.class);
+		cr.add(Restrictions.eq("name",riskType));
+		data = (SafePolicyWarning) cr.list().get(0);
+		tx.commit();
+		} catch (Exception e) {
+		logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying SafePolicyWarning Table"+e);
+		}finally{
+		try{
+		session.close();
+		}catch(Exception e1){
+		logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+		}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SecurityZoneDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SecurityZoneDaoImpl.java
new file mode 100644
index 0000000..9c79773
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SecurityZoneDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.SecurityZoneDao;
+import org.openecomp.policy.rest.jpa.SecurityZone;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("SecurityZoneDao")
+public class SecurityZoneDaoImpl implements SecurityZoneDao{
+	private static final Log logger = LogFactory.getLog(SecurityZoneDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<SecurityZone> getSecurityZoneData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<SecurityZone> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(SecurityZone.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying SecurityZone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(SecurityZone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving SecurityZone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void delete(SecurityZone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting SecurityZone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(SecurityZone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating SecurityZone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getSecurityZoneDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(SecurityZone.class);
+            List<SecurityZone> attributeData = cr.list();     
+            for(int i = 0; i < attributeData.size(); i++){
+           	 data.add(attributeData.get(i).getZoneName());
+           }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying SecurityZone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceDictionaryDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceDictionaryDaoImpl.java
new file mode 100644
index 0000000..226c500
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceDictionaryDaoImpl.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ServiceDictionaryDao;
+import org.openecomp.policy.rest.jpa.ClosedLoopD2Services;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ServiceDictionaryDao")
+public class ServiceDictionaryDaoImpl implements ServiceDictionaryDao {
+	private static final Log logger = LogFactory.getLog(ServiceDictionaryDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ClosedLoopD2Services> getClosedLoopD2ServicesData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<ClosedLoopD2Services> closedLoopD2ServicesData = null;
+        try {
+        	Criteria cr = session.createCriteria(ClosedLoopD2Services.class);
+            closedLoopD2ServicesData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ClosedLoopD2Services Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return closedLoopD2ServicesData;
+		
+	}
+
+	@Override
+	public void Save(ClosedLoopD2Services closedLoopD2Services) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(closedLoopD2Services);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ClosedLoopD2Services Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(ClosedLoopD2Services closedLoopD2Services) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(closedLoopD2Services);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ClosedLoopD2Services Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ClosedLoopD2Services closedLoopD2Services) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(closedLoopD2Services);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ClosedLoopD2Services Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getCLServiceDictDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(ClosedLoopD2Services.class);
+            List<ClosedLoopD2Services> closedLoopD2ServicesData = cr.list();      
+            for(int i = 0; i < closedLoopD2ServicesData.size(); i++){
+            	 data.add(closedLoopD2ServicesData.get(i).getServiceName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ClosedLoopD2Services Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceGroupDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceGroupDaoImpl.java
new file mode 100644
index 0000000..7256313
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceGroupDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ServiceGroupDao;
+import org.openecomp.policy.rest.jpa.GroupServiceList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ServiceGroupDao")
+public class ServiceGroupDaoImpl implements ServiceGroupDao{
+	private static final Log logger = LogFactory.getLog(ServiceGroupDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<GroupServiceList> getGroupServiceListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<GroupServiceList> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(GroupServiceList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying GroupServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(GroupServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving GroupServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(GroupServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting GroupServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(GroupServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating GroupServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getGroupServiceDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(GroupServiceList.class);
+            List<GroupServiceList> attributeData = cr.list();      
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getGroupName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying GroupServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceListDaoImpl.java
new file mode 100644
index 0000000..01ff3e4
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ServiceListDaoImpl.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ServiceListDao;
+import org.openecomp.policy.rest.jpa.ServiceList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ServiceListDao")
+public class ServiceListDaoImpl implements ServiceListDao {
+	private static final Log logger = LogFactory.getLog(ServiceListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ServiceList> getServiceListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<ServiceList> attributeData =  null;
+        try {
+        	Criteria cr = session.createCriteria(ServiceList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(ServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(ServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ServiceList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getServiceListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(ServiceList.class);
+            List<ServiceList> attributeData = cr.list();    
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getServiceName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ServiceList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+		
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SiteDictionaryDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SiteDictionaryDaoImpl.java
new file mode 100644
index 0000000..3b2a751
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/SiteDictionaryDaoImpl.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.SiteDictionaryDao;
+import org.openecomp.policy.rest.jpa.ClosedLoopSite;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+
+@Service("SiteDictionaryDao")
+public class SiteDictionaryDaoImpl implements SiteDictionaryDao {
+	private static final Log logger = LogFactory.getLog(SiteDictionaryDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<ClosedLoopSite> getClosedLoopSiteData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<ClosedLoopSite> closedLoopSiteData = null;
+        try {
+        	Criteria cr = session.createCriteria(ClosedLoopSite.class);
+            closedLoopSiteData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ClosedLoopSite Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return closedLoopSiteData;
+		
+	}
+
+	@Override
+	public void Save(ClosedLoopSite closedLoopSite) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(closedLoopSite);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving ClosedLoopSite Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(ClosedLoopSite closedLoopSite) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(closedLoopSite);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting ClosedLoopSite Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(ClosedLoopSite closedLoopSite) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(closedLoopSite);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating ClosedLoopSite Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getCLSiteDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(ClosedLoopSite.class);
+            List<ClosedLoopSite> closedLoopSiteData = cr.list();        
+            for(int i = 0; i < closedLoopSiteData.size(); i++){
+            	 data.add(closedLoopSiteData.get(i).getSiteName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying ClosedLoopSite Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/TermListDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/TermListDaoImpl.java
new file mode 100644
index 0000000..7568d60
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/TermListDaoImpl.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.TermListDao;
+import org.openecomp.policy.rest.jpa.TermList;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("TermListDao")
+public class TermListDaoImpl implements TermListDao{
+	private static final Log logger = LogFactory.getLog(TermListDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<TermList> getTermListData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<TermList> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(TermList.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(TermList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(TermList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(TermList attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getTermListDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(TermList.class);
+            List<TermList> attributeData = cr.list();   
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getTermName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+	
+	@Override
+	public TermList getTermListValueByName(String name) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		TermList data = null;
+		try {
+			Criteria cr = session.createCriteria(TermList.class);
+			cr.add(Restrictions.eq("termName",name));
+			data = (TermList) cr.list().get(0);
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying TermList Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/UserInfoDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/UserInfoDaoImpl.java
new file mode 100644
index 0000000..04ad69c
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/UserInfoDaoImpl.java
@@ -0,0 +1,138 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.UserInfoDao;
+import org.openecomp.policy.rest.jpa.UserInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+
+@Service("UserInfoDao")
+public class UserInfoDaoImpl implements UserInfoDao{
+	private static final Log logger = LogFactory.getLog(UserInfoDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@Override
+	public void save(UserInfo userInfo) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(userInfo);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving UserInfo Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}	
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<UserInfo> getUserInfo() {
+		System.out.println("UserInfoDaoImpl:  getUserInfo().. getting user info before save()");
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<UserInfo> userData = null;
+        try {
+        	Criteria cr = session.createCriteria(UserInfo.class);
+            userData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying UserInfo Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return userData;
+	}
+
+	@Override
+	public String getUserName(String loginid) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		UserInfo user = null;
+		try {
+			user = (UserInfo) session.get(UserInfo.class, loginid);
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying UserInfo Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return user.getUserName().toString();
+	}
+
+	@Override
+	public UserInfo getUserInfoByLoginId(String loginid) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		UserInfo userData = null;
+        try {
+        	Criteria cr = session.createCriteria(UserInfo.class);
+        	cr.add(Restrictions.eq("userLoginId", loginid));
+            userData = (UserInfo) cr.list().get(0);
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying UserInfo Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return userData;
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VNFTypeDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VNFTypeDaoImpl.java
new file mode 100644
index 0000000..4d424fa
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VNFTypeDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.VNFTypeDao;
+import org.openecomp.policy.rest.jpa.VNFType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("VNFTypeDao")
+public class VNFTypeDaoImpl implements VNFTypeDao {
+	private static final Log logger = LogFactory.getLog(VNFTypeDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<VNFType> getVNFTypeData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<VNFType> vnfTypeData = null;
+        try {
+        	Criteria cr = session.createCriteria(VNFType.class);
+            vnfTypeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VNFType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return vnfTypeData;
+		
+	}
+
+	@Override
+	public void Save(VNFType vnfType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(vnfType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving VNFType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(VNFType vnfType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(vnfType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting VNFType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(VNFType vnfType) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(vnfType);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating VNFType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getVNFTypeDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(VNFType.class);
+            List<VNFType> vnfTypeData = cr.list();    
+            for(int i = 0; i < vnfTypeData.size(); i++){
+            	 data.add(vnfTypeData.get(i).getVnftype());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VNFType Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+		
+	}
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VSCLActionDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VSCLActionDaoImpl.java
new file mode 100644
index 0000000..8ab6bfd
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VSCLActionDaoImpl.java
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.VSCLActionDao;
+import org.openecomp.policy.rest.jpa.VSCLAction;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("VSCLActionDao")
+public class VSCLActionDaoImpl implements VSCLActionDao{
+	private static final Log logger = LogFactory.getLog(VSCLActionDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<VSCLAction> getVSCLActionData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<VSCLAction> vSCLActionData = null;
+        try {
+        	Criteria cr = session.createCriteria(VSCLAction.class);
+            vSCLActionData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VSCLAction Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return vSCLActionData;
+		
+	}
+
+	@Override
+	public void Save(VSCLAction vSCLAction) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(vSCLAction);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving VSCLAction Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(VSCLAction vSCLAction) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(vSCLAction);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting VSCLAction Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(VSCLAction vSCLAction) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(vSCLAction);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating VSCLAction Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getVsclActionDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(VSCLAction.class);
+            List<VSCLAction> vSCLActionData = cr.list();     
+            for(int i = 0; i < vSCLActionData.size(); i++){
+            	 data.add(vSCLActionData.get(i).getVsclaction());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VSCLAction Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VarbindDictionaryDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VarbindDictionaryDaoImpl.java
new file mode 100644
index 0000000..dba3a0d
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/VarbindDictionaryDaoImpl.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.VarbindDictionaryDao;
+import org.openecomp.policy.rest.jpa.VarbindDictionary;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("VarbindDictionaryDao")
+public class VarbindDictionaryDaoImpl implements VarbindDictionaryDao {
+	private static final Log logger = LogFactory.getLog(VarbindDictionaryDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<VarbindDictionary> getVarbindDictionaryData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<VarbindDictionary> varbindDictionaryData = null;
+        try {
+        	Criteria cr = session.createCriteria(VarbindDictionary.class);
+            varbindDictionaryData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return varbindDictionaryData;
+		
+	}
+
+	@Override
+	public void Save(VarbindDictionary varbindDictionary) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(varbindDictionary);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(VarbindDictionary varbindDictionary) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(varbindDictionary);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(VarbindDictionary varbindDictionary) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(varbindDictionary);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getVarbindDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(VarbindDictionary.class);
+            List<VarbindDictionary> varbindDictionaryData = cr.list();
+            for(int i = 0; i < varbindDictionaryData.size(); i++){
+            	 data.add(varbindDictionaryData.get(i).getVarbindName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+	@Override
+	public List<VarbindDictionary> getVarbindEntityByName(String value) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<VarbindDictionary> data = null;
+		try {
+			Criteria cr = session.createCriteria(VarbindDictionary.class);
+			cr.add(Restrictions.eq("varbindName",value));
+			data = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying VarbindDictionary Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ZoneDaoImpl.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ZoneDaoImpl.java
new file mode 100644
index 0000000..865a085
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/daoimpl/ZoneDaoImpl.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.daoimpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.openecomp.policy.pap.xacml.rest.HibernateSession;
+import org.openecomp.policy.rest.dao.ZoneDao;
+import org.openecomp.policy.rest.jpa.Zone;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+@Service("ZoneDao")
+public class ZoneDaoImpl implements ZoneDao{
+	private static final Log logger = LogFactory.getLog(ZoneDaoImpl.class);
+	@Autowired
+	SessionFactory sessionfactory;
+	
+	public SessionFactory getSessionfactory() {
+		return sessionfactory;
+	}
+
+	public void setSessionfactory(SessionFactory sessionfactory) {
+		this.sessionfactory = sessionfactory;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<Zone> getZoneData() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<Zone> attributeData = null;
+        try {
+        	Criteria cr = session.createCriteria(Zone.class);
+            attributeData = cr.list();
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying Zone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return attributeData;
+		
+	}
+
+	@Override
+	public void Save(Zone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.persist(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Saving Zone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@Override
+	public void delete(Zone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.delete(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Deleting Zone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+	}
+
+	@Override
+	public void update(Zone attribute) {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		try {
+			session.update(attribute);
+			tx.commit();	
+		}catch(Exception e){
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Updating Zone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public List<String> getZoneDataByName() {
+		Session session = HibernateSession.getSessionFactory();
+		Transaction tx = session.beginTransaction();
+		List<String> data = new ArrayList<String>();
+        try {
+        	Criteria cr = session.createCriteria(Zone.class);
+            List<Zone> attributeData = cr.list();
+            
+            for(int i = 0; i < attributeData.size(); i++){
+            	 data.add(attributeData.get(i).getZoneName());
+            }
+			tx.commit();
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Querying Zone Table"+e);	
+		}finally{
+			try{
+				session.close();
+			}catch(Exception e1){
+				logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement"+e1);
+			}
+		}
+		return data;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/PDPPolicyContainer.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/PDPPolicyContainer.java
new file mode 100644
index 0000000..e91c79a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/PDPPolicyContainer.java
@@ -0,0 +1,349 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.model;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.openecomp.policy.pap.xacml.rest.util.PolicyContainer;
+import org.openecomp.policy.pap.xacml.rest.util.PolicyItemSetChangeNotifier;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.api.pap.PDP;
+import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPolicy;
+import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class PDPPolicyContainer extends PolicyItemSetChangeNotifier implements PolicyContainer.Indexed {
+	private static final long serialVersionUID = 1L;
+	private static Logger logger	= FlexLogger.getLogger(PDPPolicyContainer.class);
+	
+	 /**
+     * String identifier of a file's "Id" property.
+     */
+    public static String PROPERTY_ID = "Id";
+
+   /**
+     * String identifier of a file's "name" property.
+     */
+    public static String PROPERTY_NAME = "Name";
+
+    /**
+      * String identifier of a file's "name" property.
+      */
+     public static String PROPERTY_VERSION = "Version";
+     
+    /**
+     * String identifier of a file's "Description" property.
+     */
+    public static String PROPERTY_DESCRIPTION = "Description";
+    
+    /**
+     * String identifier of a file's "IsRoot" property.
+     */
+    public static String PROPERTY_ISROOT = "Root";
+
+    /**
+     * List of the string identifiers for the available properties.
+     */
+    public static Collection<String> PDPPOLICY_PROPERTIES;
+ 
+    private final Object data;
+    private List<PDPPolicy> policies;
+    
+	@SuppressWarnings("unchecked")
+	public PDPPolicyContainer(Object data) {
+		super();
+		this.data = data;
+		if (this.data instanceof PDPGroup) {
+			policies = new ArrayList<PDPPolicy> (((PDPGroup) this.data).getPolicies());
+		}
+		if (this.data instanceof PDP) {
+			policies = new ArrayList<PDPPolicy> (((PDP) this.data).getPolicies());
+		}
+		if (this.data instanceof Set) {
+			policies = new ArrayList<PDPPolicy> ((Set<PDPPolicy>)data);
+		}
+		if (this.policies == null) {
+			logger.info("NULL policies");
+			throw new NullPointerException("PDPPolicyContainer created with unexpected Object type '" + data.getClass().getName() + "'");
+		}
+		this.setContainer(this);
+	}
+	
+	@Override
+	public Object nextItemId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("nextItemId: " + itemId);
+		}
+		int index = this.policies.indexOf(itemId);
+		if (index == -1 || ((index + 1) >= this.policies.size())) {
+			return null;
+		}		
+		return new PDPPolicyItem(this.policies.get(index + 1));
+	}
+
+	@Override
+	public Object prevItemId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("prevItemId: " + itemId);
+		}
+		int index = this.policies.indexOf(itemId);
+		if (index <= 0) {
+			return null;
+		}
+		return new PDPPolicyItem(this.policies.get(index - 1));
+	}
+
+	@Override
+	public Object firstItemId() {
+		if (logger.isTraceEnabled()) {
+			logger.trace("firstItemId: ");
+		}
+		if (this.policies.isEmpty()) {
+			return null;
+		}
+		return new PDPPolicyItem(this.policies.get(0));
+	}
+
+	@Override
+	public Object lastItemId() {
+		if (logger.isTraceEnabled()) {
+			logger.trace("lastItemid: ");
+		}
+		if (this.policies.isEmpty()) {
+			return null;
+		}
+		return new PDPPolicyItem(this.policies.get(this.policies.size() - 1));
+	}
+
+	@Override
+	public boolean isFirstId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("isFirstId: " + itemId);
+		}
+		if (this.policies.isEmpty()) {
+			return false;
+		}
+		return (itemId.equals(this.policies.get(0)));
+	}
+
+	@Override
+	public boolean isLastId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("isLastId: " + itemId);
+		}
+		if (this.policies.isEmpty()) {
+			return false;
+		}
+		return (itemId.equals(this.policies.get(this.policies.size() - 1)));
+	}
+
+	@Override
+	public Object addItemAfter(Object previousItemId)
+			throws UnsupportedOperationException {
+		return null;
+	}
+
+	@Override
+	public Collection<?> getContainerPropertyIds() {
+		return PDPPOLICY_PROPERTIES;
+	}
+
+	@Override
+	public Collection<?> getItemIds() {
+		final Collection<Object> items = new ArrayList<Object>();
+		items.addAll(this.policies);
+		return Collections.unmodifiableCollection(items);
+	}
+	
+	
+	@Override
+	public Class<?> getType(Object propertyId) {
+        if (propertyId.equals(PROPERTY_ID)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_NAME)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_VERSION)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_DESCRIPTION)) {
+            return String.class;
+        }
+        if (propertyId.equals(PROPERTY_ISROOT)) {
+            return Boolean.class;
+        }
+		return null;
+	}
+
+	@Override
+	public int size() {
+		if (logger.isTraceEnabled()) {
+			logger.trace("size: " + this.policies.size());
+		}
+		return this.policies.size();
+	}
+
+	@Override
+	public boolean containsId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("containsId: " + itemId);
+		}
+		return this.policies.contains(itemId);
+	}
+
+	@Override
+	public Object addItem() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Cannot add an empty policy.");
+	}
+
+	@Override
+	public boolean removeItem(Object itemId)
+			throws UnsupportedOperationException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("removeItem: " + itemId);
+		}
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		StdPDPPolicy pdpPolicy = null;
+		try {
+			pdpPolicy = mapper.readValue(itemId.toString() , StdPDPPolicy.class);
+			for(int i = 0; i< policies.size(); i++){
+				if(policies.get(i).getId().equalsIgnoreCase(pdpPolicy.getId())){
+					return this.policies.remove(this.policies.get(i));
+				}
+			}
+		} catch (Exception e) {
+			logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Exception Occured While Mapping the Removing Policy from PDP Group to Std Policy"+e);
+		}	
+		return this.policies.remove(itemId);
+	}
+
+	@Override
+	public boolean addContainerProperty(Object propertyId, Class<?> type,
+			Object defaultValue) throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeContainerProperty(Object propertyId)
+			throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public boolean removeAllItems() throws UnsupportedOperationException {
+		return false;
+	}
+
+	@Override
+	public int indexOfId(Object itemId) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("indexOfId: " + itemId);
+		}
+		return this.policies.indexOf(itemId);
+	}
+
+	@Override
+	public Object getIdByIndex(int index) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("getIdByIndex: " + index);
+		}
+		return this.policies.get(index);
+	}
+
+	@Override
+	public List<?> getItemIds(int startIndex, int numberOfItems) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("getItemIds: " + startIndex + " " + numberOfItems);
+		}
+		if (numberOfItems < 0) {
+			throw new IllegalArgumentException();
+		}
+		return this.policies.subList(startIndex, startIndex + numberOfItems);
+	}
+
+	@Override
+	public Object addItemAt(int index) throws UnsupportedOperationException {
+		if (logger.isTraceEnabled()) {
+			logger.trace("addItemAt: " + index);
+		}
+		return null;
+	}
+
+	public class PDPPolicyItem {
+		private final PDPPolicy policy;
+		
+		public PDPPolicyItem(PDPPolicy itemId) {
+			this.policy = itemId;
+		}
+
+		public String getId() {
+			if (logger.isTraceEnabled()) {
+				logger.trace("getId: " + this.policy);
+			}
+			return this.policy.getId();
+		}
+		
+		public String getName() {
+			if (logger.isTraceEnabled()) {
+				logger.trace("getName: " + this.policy);
+			}
+			return this.policy.getName();
+		}
+		
+		public String getVersion() {
+			if (logger.isTraceEnabled()) {
+				logger.trace("getVersion: " + this.policy);
+			}
+			return this.policy.getVersion();
+		}
+		
+		public String getDescription() {
+			if (logger.isTraceEnabled()) {
+				logger.trace("getDescription: " + this.policy);
+			}
+			return this.policy.getDescription();
+		}
+		
+		public boolean getRoot() {
+			if (logger.isTraceEnabled()) {
+				logger.trace("isRoot: " + this.policy);
+			}
+			return this.policy.isRoot();
+		}
+		
+		public void setRoot(Boolean root) {
+			((StdPDPPolicy)this.policy).setRoot(root);
+		}
+	
+	}
+}
\ No newline at end of file
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/RemoveGroupPolicy.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/RemoveGroupPolicy.java
new file mode 100644
index 0000000..bb6e118
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/RemoveGroupPolicy.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.model;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.openecomp.policy.pap.xacml.rest.model.PDPPolicyContainer;
+
+import com.att.research.xacml.api.pap.PDPGroup;
+import com.att.research.xacml.api.pap.PDPPolicy;
+
+import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
+import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
+
+public class RemoveGroupPolicy {
+
+	
+	//Container from where we are fetching the policies
+	private static PDPPolicyContainer policyContainer;
+		
+	private final RemoveGroupPolicy self = this;
+	private StdPDPGroup updatedObject;
+	private final StdPDPGroup group;
+	private boolean isSaved = false;
+	
+	public RemoveGroupPolicy(StdPDPGroup group) {
+		
+		this.group = group;
+		
+	}
+	
+	public void prepareToRemove(PDPPolicy policy) {
+		
+		if (this.group == null) {
+			return;
+		}
+
+		RemoveGroupPolicy.policyContainer = new PDPPolicyContainer(group);
+
+		RemoveGroupPolicy.policyContainer.removeItem(policy);
+									
+		self.doSave();
+		
+		self.isSaved = true;
+		
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected void doSave() {
+		if (this.group == null) {
+			return;
+		}
+		
+		//StdPDPGroup pdpGroup = (StdPDPGroup) group;
+		StdPDPGroup updatedGroupObject = new StdPDPGroup(
+				group.getId(), 
+				group.isDefaultGroup(), 
+				group.getName(), 
+				group.getDescription(), 
+				null);
+		
+		// replace the original set of Policies with the set from the container (possibly modified by the user)
+		Set<PDPPolicy> changedPolicies = new HashSet<PDPPolicy>();
+		changedPolicies.addAll((Collection<PDPPolicy>) RemoveGroupPolicy.policyContainer.getItemIds());
+		updatedGroupObject.setPolicies(changedPolicies);
+		updatedGroupObject.setEcompPdps(this.group.getEcompPdps());
+		
+		// replace the original set of PIP Configs with the set from the container
+		updatedGroupObject.setPipConfigs(this.group.getPipConfigs());
+		
+		// copy those things that the user cannot change from the original to the new object
+		updatedGroupObject.setStatus(this.group.getStatus());
+		
+		this.updatedObject = updatedGroupObject;			
+	}
+	
+	public boolean isRemoved() {
+		return this.isSaved;
+	}
+		
+	public EcompPDPGroup getUpdatedObject() {
+		return this.updatedObject;
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/package-info.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/package-info.java
new file mode 100644
index 0000000..4f7d76a
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/model/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * 
+ */
+/**
+ *
+ */
+package org.openecomp.policy.pap.xacml.rest.model;
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JPAUtils.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JPAUtils.java
new file mode 100644
index 0000000..5326cb2
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JPAUtils.java
@@ -0,0 +1,242 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Query;
+import javax.servlet.ServletException;
+
+import org.openecomp.policy.rest.XacmlAdminAuthorization;
+import org.openecomp.policy.rest.jpa.Attribute;
+import org.openecomp.policy.rest.jpa.Datatype;
+import org.openecomp.policy.rest.jpa.FunctionDefinition;
+import org.openecomp.policy.rest.jpa.GlobalRoleSettings;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+public class JPAUtils {
+	private static Logger logger	= FlexLogger.getLogger(JPAUtils.class);
+	
+	private EntityManagerFactory emf;
+	private static final Object mapAccess = new Object();
+	private static Map<Datatype, List<FunctionDefinition>> mapDatatype2Function = null;
+	private static Map<String, FunctionDefinition> mapID2Function = null;
+	private static JPAUtils currentInstance = null;
+	
+	//private static List<LockdownListener> lockdownListeners = new ArrayList<LockdownListener>();
+	
+	/**
+	 * Get an instance of a JPAUtils. It creates one if it does not exist.
+	 * Only one instance is allowed to be created per server.
+	 * @param emf The EntityFactoryManager to be used for database connections
+	 * @return The new instance of JPAUtils or throw exception if the given emf is null.
+	 * @throws IllegalStateException if a JPAUtils has already been constructed. Call getJPAUtilsInstance() to get this.
+	 */
+	public static JPAUtils getJPAUtilsInstance(EntityManagerFactory emf) throws Exception{
+		logger.debug("getJPAUtilsInstance(EntityManagerFactory emf) as getJPAUtilsInstance("+emf+") called");
+		if(currentInstance == null){
+			if(emf != null){
+				currentInstance = new JPAUtils(emf);
+				return currentInstance;
+			}
+			throw new IllegalStateException("The EntityManagerFactory is Null");
+		}
+		return currentInstance;
+	}
+	
+	private JPAUtils(EntityManagerFactory emf){
+		logger.debug("JPAUtils(EntityManagerFactory emf) as JPAUtils("+emf+") called");
+		this.emf = emf;	
+	}
+	
+	/**
+	 * Gets the current instance of JPAUtils. 
+	 * @return The instance of JPAUtils or throws exception if the given instance is null.
+	 * @throws IllegalStateException if a JPAUtils instance is null. Call getJPAUtilsInstance(EntityManagerFactory emf) to get this.
+	 */
+	public static JPAUtils getJPAUtilsInstance() throws Exception{
+		logger.debug("getJPAUtilsInstance() as getJPAUtilsInstance() called");
+		if(currentInstance != null){
+			return currentInstance;
+		}
+		throw new IllegalStateException("The JPAUtils.currentInstance is Null.  Use getJPAUtilsInstance(EntityManagerFactory emf)");
+	}
+	
+	public static AttributeDesignatorType	createDesignator(Attribute attribute) {
+		AttributeDesignatorType designator = new AttributeDesignatorType();
+		designator.setAttributeId(attribute.getXacmlId());
+		if (attribute.getCategoryBean() != null) {
+			designator.setCategory(attribute.getCategoryBean().getXacmlId());
+		} else {
+			logger.warn("No category bean");
+		}
+		if (attribute.getDatatypeBean() != null) {
+			designator.setDataType(attribute.getDatatypeBean().getXacmlId());
+		} else {
+			logger.warn("No datatype bean");
+		}
+		designator.setIssuer(attribute.getIssuer());
+		designator.setMustBePresent(attribute.isMustBePresent());
+		return designator;
+	}
+		
+	public static AttributeSelectorType	createSelector(Attribute attribute) {
+		AttributeSelectorType selector = new AttributeSelectorType();
+		selector.setContextSelectorId(attribute.getXacmlId());
+		selector.setPath(attribute.getSelectorPath());
+		if (attribute.getCategoryBean() != null) {
+			selector.setCategory(attribute.getCategoryBean().getXacmlId());
+		} else {
+			logger.warn("No category bean");
+		}
+		if (attribute.getDatatypeBean() != null) {
+			selector.setDataType(attribute.getDatatypeBean().getXacmlId());
+		} else {
+			logger.warn("No datatype bean");
+		}
+		selector.setMustBePresent(attribute.isMustBePresent());
+		return selector;
+	}
+	
+	/**
+	 * Builds a map in memory of a functions return datatype to function definition. Useful in limiting the number
+	 * of SQL calls to DB especially when we don't expect these to change much.
+	 * 
+	 * @return - A HashMap of Datatype JPA Container ID's to FunctionDefinition objects
+	 */
+	public Map<Datatype, List<FunctionDefinition>>	getFunctionDatatypeMap() {		
+		
+		synchronized(mapAccess) {
+			if (mapDatatype2Function == null||mapDatatype2Function.isEmpty()) {
+				try {
+					buildFunctionMaps();
+				} catch (ServletException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		return mapDatatype2Function;
+	}
+	
+	public Map<String, FunctionDefinition> getFunctionIDMap() {
+		synchronized(mapAccess) {
+			if (mapID2Function == null||mapID2Function.equals("{}")) {
+				try {
+					buildFunctionMaps();
+				} catch (ServletException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		return mapID2Function;
+	}
+	
+	private void buildFunctionMaps() throws ServletException {
+		mapDatatype2Function = new HashMap<Datatype, List<FunctionDefinition>>();
+		mapID2Function = new HashMap<String, FunctionDefinition>();
+
+		EntityManager em = emf.createEntityManager();
+		Query getFunctionDefinitions = em.createNamedQuery("FunctionDefinition.findAll");	
+		List<?> functionList = getFunctionDefinitions.getResultList(); 	
+		
+		for (Object id : functionList) {
+			FunctionDefinition value = (FunctionDefinition)id;
+			mapID2Function.put(value.getXacmlid(), value);
+			if (mapDatatype2Function.containsKey(value.getDatatypeBean()) == false) {
+				mapDatatype2Function.put(value.getDatatypeBean(), new ArrayList<FunctionDefinition>());
+			}
+			mapDatatype2Function.get(value.getDatatypeBean()).add(value);
+		}
+
+		em.close();
+		
+	}
+	
+	/**
+	 * Returns the lockdown value, in case of exception it is assumed that lockdown functionality
+	 * is not supported and returns false.
+	 * 
+	 * 
+	 * @throws ReadOnlyException
+	 * @throws ConversionException
+	 */
+	public boolean dbLockdownIgnoreErrors() {
+		if (logger.isTraceEnabled())
+			logger.trace("ENTER");
+		
+		boolean lockdown = false;
+		try {
+			lockdown = dbLockdown();
+		} catch (Exception e) {
+			logger.warn("Cannot access DB lockdown value", e);
+		}
+		return lockdown;
+	}
+	
+	/**
+	 * Returns the lockdown value from the database.
+	 * 
+	 * @throws ReadOnlyException
+	 * @throws ConversionException
+	 */
+	public boolean dbLockdown() 
+			throws  IllegalAccessException {
+		if (logger.isTraceEnabled())
+			logger.trace("ENTER");
+		
+		EntityManager em = emf.createEntityManager();
+		Query globalRoleSettingsJPA = em.createNamedQuery("GlobalRoleSettings.findAll");	
+		
+		GlobalRoleSettings globalRoleSettings = (GlobalRoleSettings) globalRoleSettingsJPA.getSingleResult();
+		
+		if (globalRoleSettings == null) {
+			// this should not happen
+			String msg = "NO GlobalSetttings for " + XacmlAdminAuthorization.Role.ROLE_SUPERADMIN.toString();
+			if (logger.isErrorEnabled())
+				logger.error(msg);
+			throw new IllegalAccessException(msg);
+		}
+		
+		if (!globalRoleSettings.getRole().equals(XacmlAdminAuthorization.Role.ROLE_SUPERADMIN.toString())) {
+			String msg = "NOT FOUND db data for " + XacmlAdminAuthorization.Role.ROLE_SUPERADMIN.toString();
+			if (logger.isErrorEnabled())
+				logger.error(msg);
+			throw new IllegalAccessException(msg);
+		}
+		
+		return globalRoleSettings.isLockdown();
+	}
+	
+	
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JsonMessage.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JsonMessage.java
new file mode 100644
index 0000000..3e93510
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/JsonMessage.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.rest.util;
+
+public class JsonMessage {
+
+	private String data;
+	private String data2;
+	private String data3;
+	public JsonMessage(String data) {
+		super();
+		this.data = data;
+	}
+	public JsonMessage(String data,String data2) {
+		super();
+		this.data = data;
+		this.data2 = data2;
+	}
+
+	public JsonMessage(String data,String data2,String data3) {
+		super();
+		this.data = data;
+		this.data2 = data2;
+		this.data3 = data3;
+	}
+	
+	public String getData() {
+		return data;
+	}
+
+	public void setData(String data) {
+		this.data = data;
+	}
+	public String getData2() {
+		return data2;
+	}
+	public void setData2(String data2) {
+		this.data2 = data2;
+	}
+	public String getData3() {
+		return data3;
+	}
+	public void setData3(String data3) {
+		this.data3 = data3;
+	}
+	
+	
+}
+
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyContainer.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyContainer.java
new file mode 100644
index 0000000..3741dbd
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyContainer.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP Policy Engine
+ * ================================================================================
+ * 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.pap.xacml.rest.util;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+
+public interface PolicyContainer extends Serializable{
+	
+    public Collection<?> getContainerPropertyIds();
+    
+    public Collection<?> getItemIds();
+
+    public Class<?> getType(Object propertyId);
+
+    public int size();
+  
+    public boolean containsId(Object itemId);
+
+    public Object addItem() throws UnsupportedOperationException;
+    
+    public boolean removeItem(Object itemId)
+            throws UnsupportedOperationException;
+
+    public boolean addContainerProperty(Object propertyId, Class<?> type,
+            Object defaultValue) throws UnsupportedOperationException;
+   
+    public boolean removeContainerProperty(Object propertyId)
+            throws UnsupportedOperationException;
+
+    public boolean removeAllItems() throws UnsupportedOperationException;
+
+    public interface Ordered extends PolicyContainer {
+
+        public Object nextItemId(Object itemId);
+
+        public Object prevItemId(Object itemId);
+
+        public Object firstItemId();
+
+        public Object lastItemId();
+
+        public boolean isFirstId(Object itemId);
+
+        public boolean isLastId(Object itemId);
+
+        public Object addItemAfter(Object previousItemId)
+                throws UnsupportedOperationException;
+        
+    }
+
+    
+    public interface Indexed extends Ordered {
+
+        public int indexOfId(Object itemId);
+
+        public Object getIdByIndex(int index);
+
+        public List<?> getItemIds(int startIndex, int numberOfItems);
+        
+        public Object addItemAt(int index) throws UnsupportedOperationException;
+
+        public interface ItemAddEvent extends ItemSetChangeEvent {
+
+            public Object getFirstItemId();
+
+            public int getFirstIndex();
+
+            public int getAddedItemsCount();
+        }
+
+     
+        public interface ItemRemoveEvent extends ItemSetChangeEvent {
+          
+            public Object getFirstItemId();
+
+            public int getFirstIndex();
+
+            public int getRemovedItemsCount();
+        }
+    }
+  
+    public interface ItemSetChangeEvent extends Serializable {
+
+        public PolicyContainer getContainer();
+    }
+
+    public interface ItemSetChangeListener extends Serializable {
+
+        public void containerItemSetChange(PolicyContainer.ItemSetChangeEvent event);
+    }
+
+    public interface ItemSetChangeNotifier extends Serializable {
+
+        public void addItemSetChangeListener(
+                PolicyContainer.ItemSetChangeListener listener);
+
+        public void removeItemSetChangeListener(
+                PolicyContainer.ItemSetChangeListener listener);
+    }
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyItemSetChangeNotifier.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyItemSetChangeNotifier.java
new file mode 100644
index 0000000..da92784
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/util/PolicyItemSetChangeNotifier.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP Policy Engine
+ * ================================================================================
+ * 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.pap.xacml.rest.util;
+
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.EventObject;
+import java.util.LinkedList;
+
+import org.openecomp.policy.pap.xacml.rest.util.PolicyContainer.ItemSetChangeEvent;
+import org.openecomp.policy.pap.xacml.rest.util.PolicyContainer.ItemSetChangeListener;
+
+
+
+
+public class PolicyItemSetChangeNotifier implements PolicyContainer.ItemSetChangeNotifier {
+	private static final long serialVersionUID = 1L;
+    private Collection<PolicyContainer.ItemSetChangeListener> itemSetChangeListeners = null;
+    private PolicyContainer container = null;
+    
+    public PolicyItemSetChangeNotifier() {
+    }
+    
+    protected void setContainer(PolicyContainer c) {
+    	this.container = c;
+    }
+
+	@Override
+	public void addItemSetChangeListener(ItemSetChangeListener listener) {
+        if (getItemSetChangeListeners() == null) {
+            setItemSetChangeListeners(new LinkedList<PolicyContainer.ItemSetChangeListener>());
+        }
+        getItemSetChangeListeners().add(listener);	}
+
+	@Override
+	public void removeItemSetChangeListener(ItemSetChangeListener listener) {
+        if (getItemSetChangeListeners() != null) {
+            getItemSetChangeListeners().remove(listener);
+        }
+    }
+	
+	protected static class BaseItemSetChangeEvent extends EventObject implements
+	    PolicyContainer.ItemSetChangeEvent, Serializable {
+		private static final long serialVersionUID = 1L;
+
+		protected BaseItemSetChangeEvent(PolicyContainer source) {
+		    super(source);
+		}
+		
+		@Override
+		public PolicyContainer getContainer() {
+		    return (PolicyContainer) getSource();
+		}
+	}
+
+    protected void setItemSetChangeListeners(
+            Collection<PolicyContainer.ItemSetChangeListener> itemSetChangeListeners) {
+        this.itemSetChangeListeners = itemSetChangeListeners;
+    }
+    protected Collection<PolicyContainer.ItemSetChangeListener> getItemSetChangeListeners() {
+        return itemSetChangeListeners;
+    }
+  
+    protected void fireItemSetChange() {
+        fireItemSetChange(new BaseItemSetChangeEvent(this.container));
+    }
+
+    protected void fireItemSetChange(ItemSetChangeEvent event) {
+        if (getItemSetChangeListeners() != null) {
+            final Object[] l = getItemSetChangeListeners().toArray();
+            for (int i = 0; i < l.length; i++) {
+                ((PolicyContainer.ItemSetChangeListener) l[i])
+                        .containerItemSetChange(event);
+            }
+        }
+    }
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/AuthenticationService.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/AuthenticationService.java
new file mode 100644
index 0000000..003585b
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/AuthenticationService.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.restAuth;
+
+import java.util.Base64;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.rest.XACMLRestProperties;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+import com.att.research.xacml.util.XACMLProperties;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class AuthenticationService {
+	private String papID = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
+	private String papPass = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
+	private static final Logger logger = FlexLogger.getLogger(AuthenticationService.class);
+	
+	public boolean authenticate(String authCredentials) {
+
+		if (null == authCredentials)
+			return false;
+		// header value format will be "Basic encodedstring" for Basic authentication. 
+		final String encodedUserPassword = authCredentials.replaceFirst("Basic"	+ " ", "");
+		String usernameAndPassword = null;
+		try {
+			byte[] decodedBytes = Base64.getDecoder().decode(encodedUserPassword);
+			usernameAndPassword = new String(decodedBytes, "UTF-8");
+		} catch (Exception e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "AuthenticationService", "Exception decoding username and password");
+			return false;
+		}
+		try {
+			final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
+			final String username = tokenizer.nextToken();
+			final String password = tokenizer.nextToken();
+
+			boolean authenticationStatus = papID.equals(username)	&& papPass.equals(password);
+			return authenticationStatus;
+		} catch (Exception e){
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "AuthenticationService", "Exception authenticating user");
+			return false;
+		}
+	}
+	
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/CheckPDP.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/CheckPDP.java
new file mode 100644
index 0000000..ce35a70
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/CheckPDP.java
@@ -0,0 +1,203 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.restAuth;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.eelf.PolicyLogger;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet;
+
+import org.openecomp.policy.xacml.api.XACMLErrorConstants;
+
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
+import org.openecomp.policy.common.logging.flexlogger.Logger; 
+
+public class CheckPDP {
+
+	private static Path pdpPath = null;
+	private static Properties pdpProp = null;
+	private static Long oldModified = null;
+	private static Long newModified = null;
+	private static HashMap<String, String> pdpMap = null;
+	private static final Logger logger = FlexLogger.getLogger(CheckPDP.class);
+
+	public static boolean validateID(String id) {
+		// ReadFile
+		try {
+			readFile();
+		} catch (Exception e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "CheckPDP", "Exception reading file");
+			return false;
+		}
+		// Check ID
+		if (pdpMap.containsKey(id)) {
+			return true;
+		}
+		return false;
+	}
+
+	private static void readFile() throws Exception {
+		String pdpFile = XACMLPapServlet.getPDPFile();
+		if (pdpFile == null) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PDP File name not Valid : " + pdpFile);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + "PDP File name is undefined");
+			throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"PDP File name not Valid : " + pdpFile);
+		}
+		if (pdpPath == null) {
+			pdpPath = Paths.get(pdpFile);
+			if (Files.notExists(pdpPath)) {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "File doesn't exist in the specified Path : "	+ pdpPath.toString());
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + "File doesn't exist in the specified Path");
+				throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"File doesn't exist in the specified Path : "+ pdpPath.toString());
+			} 
+			if (pdpPath.toString().endsWith(".properties")) {
+				readProps();
+			} else {
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file " + pdpFile);
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + "Not a .properties file");
+				throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Not a .properties file");
+			}
+		}
+		// Check if File is updated recently
+		else {
+			newModified = pdpPath.toFile().lastModified();
+			if (newModified != oldModified) {
+				// File has been updated.
+				readProps();
+			}
+		}
+	}
+
+	private static void readProps() throws Exception {
+		InputStream in;
+		pdpProp = new Properties();
+		try {
+			in = new FileInputStream(pdpPath.toFile());
+			oldModified = pdpPath.toFile().lastModified();
+			pdpProp.load(in);
+		} catch (IOException e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "CheckPDP", "Cannot load the Properties file");
+			throw new Exception("Cannot Load the Properties file", e);
+		}
+		// Read the Properties and Load the PDPs and encoding.
+		pdpMap = new HashMap<String, String>();
+		// Check the Keys for PDP_URLs
+		Collection<Object> unsorted = pdpProp.keySet();
+		List<String> sorted = new ArrayList(unsorted);
+		Collections.sort(sorted);
+		for (String propKey : sorted) {
+			if (propKey.startsWith("PDP_URL")) {
+				String check_val = pdpProp.getProperty(propKey);
+				if (check_val == null) {
+					throw new Exception("Properties file doesn't have the PDP_URL parameter");
+				}
+				if (check_val.contains(";")) {
+					List<String> pdp_default = new ArrayList<String>(Arrays.asList(check_val.split("\\s*;\\s*")));
+					int pdpCount = 0;
+					while (pdpCount < pdp_default.size()) {
+						String pdpVal = pdp_default.get(pdpCount);
+						readPDPParam(pdpVal);
+						pdpCount++;
+					}
+				} else {
+					readPDPParam(check_val);
+				}
+			}
+		}
+		if (pdpMap == null || pdpMap.isEmpty()) {
+			logger.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Cannot Proceed without PDP_URLs");
+			throw new Exception(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Cannot Proceed without PDP_URLs");
+		}
+	}
+
+	private static void readPDPParam(String pdpVal) throws Exception{
+		if(pdpVal.contains(",")){
+			List<String> pdpValues = new ArrayList<String>(Arrays.asList(pdpVal.split("\\s*,\\s*")));
+			if(pdpValues.size()==3){
+				// 1:2 will be UserID:Password
+				String userID = pdpValues.get(1);
+				String pass = pdpValues.get(2);
+				Base64.Encoder encoder = Base64.getEncoder();
+				// 0 - PDPURL
+				pdpMap.put(pdpValues.get(0), encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8)));
+			}else{
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "No Credentials to send Request: " + pdpValues);
+				PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + "No Credentials to send Request");
+				throw new Exception(XACMLErrorConstants.ERROR_PERMISSIONS + "No enough Credentials to send Request. " + pdpValues);
+			}
+		}else{
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_PERMISSIONS + "No Credentials to send Request: " + pdpVal);
+			PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + "No Credentials to send Request: " + pdpVal);
+			throw new Exception(XACMLErrorConstants.ERROR_PERMISSIONS +"No enough Credentials to send Request.");
+		}
+	}
+	
+	public static String getEncoding(String pdpID){
+		try {
+			readFile();
+		} catch (Exception e) {
+			//TODO:EELF Cleanup - Remove logger
+			//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "CheckPDP", "Exeption reading Properties file");
+		}
+		String encoding = null;
+		if(pdpMap!=null && (!pdpMap.isEmpty())){
+			try{
+				encoding = pdpMap.get(pdpID);
+			} catch(Exception e){
+				//TODO:EELF Cleanup - Remove logger
+				//logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
+				PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "CheckPDP", "Exception encoding");
+			}
+			return encoding;
+		}else{
+			return null;
+		}
+	}
+
+}
diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/PAPAuthenticationFilter.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/PAPAuthenticationFilter.java
new file mode 100644
index 0000000..8176294
--- /dev/null
+++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/restAuth/PAPAuthenticationFilter.java
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ECOMP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.policy.pap.xacml.restAuth;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet;
+
+/**
+ * Servlet Filter implementation class PAPAuthenticationFilter
+ */
+@WebFilter("/*")
+public class PAPAuthenticationFilter implements Filter {
+
+	private static final Log logger	= LogFactory.getLog(PAPAuthenticationFilter.class);
+	public static final String AUTHENTICATION_HEADER = "Authorization";
+
+	@Override
+	public void doFilter(ServletRequest request, ServletResponse response,
+			FilterChain filter) throws IOException, ServletException {
+		
+		
+		if (request instanceof HttpServletRequest) {
+			HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+
+			String authCredentials = null;
+			String url = httpServletRequest.getRequestURI();
+			
+			logger.info("Request URI: " + url);
+			System.out.println("Request URI: " + url);
+			
+			//getting authentication credentials
+			if(url.contains("@Auth@")){
+				int authIndex = url.lastIndexOf("@");
+				int endAuthIndex = url.indexOf("/ecomp");
+				authCredentials = "Basic " + url.substring(authIndex+1, endAuthIndex);
+				
+				//parse the url for /pap/ecomp/
+				String url1 = url.substring(0, 4);
+				String url2 = url.substring(endAuthIndex, url.length());
+				url = url1 + url2;
+
+			} else {
+				authCredentials = httpServletRequest.getHeader(AUTHENTICATION_HEADER);
+			}
+			
+			// Check Authentication credentials
+			AuthenticationService authenticationService = new AuthenticationService();
+			boolean authenticationStatus = authenticationService.authenticate(authCredentials);
+			
+			if (authenticationStatus) {
+				//indicates the request comes from Traditional Admin Console or PolicyEngineAPI
+				if (url.equals("/pap/")){
+					logger.info("Request comes from Traditional Admin Console or PolicyEngineAPI");						
+					
+					//forward request to the XACMLPAPServlet if authenticated
+					request.getRequestDispatcher("/pap/pap/").forward(request, response);
+					
+				}else if (url.startsWith("/pap/ecomp/")){
+					
+					//indicates the request comes from the ECOMP Portal ecomp-sdk-app
+					if(response instanceof HttpServletResponse) {
+						HttpServletResponse alteredResponse = ((HttpServletResponse)response);
+						addCorsHeader(alteredResponse);
+						logger.info("Request comes from Ecomp Portal");
+						//Spring dispatcher servlet is at the end of the filter chain at /pap/ecomp/ path
+						System.out.println("New Request URI: " + url);
+						//request.getRequestDispatcher(url).forward(request, alteredResponse);
+						filter.doFilter(request, response);
+					}
+					
+				}
+				
+			} else {
+				if (response instanceof HttpServletResponse) {
+					HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+					httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+				}
+			}
+
+		}
+	}
+	
+	//method to add CorsHeaders for ecomp portal rest call
+	private void addCorsHeader(HttpServletResponse response) {
+		logger.info("Adding Cors Response Headers!!!");
+		response.addHeader("Access-Control-Allow-Origin", "*");
+        response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
+        response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
+        response.addHeader("Access-Control-Max-Age", "1728000");	
+	}
+
+	@Override
+	public void destroy() {
+	}
+
+	@Override
+	public void init(FilterConfig arg0) throws ServletException {
+	}
+}
