Initial OpenECOMP policy/engine commit
[policy/engine.git] / ECOMP-PAP-REST / src / main / java / org / openecomp / policy / pap / xacml / rest / components / PolicyDBDao.java
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 (file)
index 0000000..bdd7534
--- /dev/null
@@ -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);
+               }
+               
+       }
+       
+}