Commit includes ControlLoopPolicy API and bugfixes
[policy/engine.git] / ECOMP-PAP-REST / src / main / java / org / openecomp / policy / pap / xacml / rest / components / PolicyDBDao.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.policy.pap.xacml.rest.components;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.File;
25 import java.io.FileFilter;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.FileWriter;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.StringReader;
33 import java.net.HttpURLConnection;
34 import java.net.MalformedURLException;
35 import java.net.ProtocolException;
36 import java.net.URL;
37 import java.nio.charset.StandardCharsets;
38 import java.nio.file.FileSystems;
39 import java.nio.file.Files;
40 import java.nio.file.InvalidPathException;
41 import java.nio.file.Path;
42 import java.nio.file.Paths;
43 import java.security.Key;
44 import java.sql.Timestamp;
45 import java.util.ArrayList;
46 import java.util.Base64;
47 import java.util.Calendar;
48 import java.util.Date;
49 import java.util.HashMap;
50 import java.util.HashSet;
51 import java.util.Iterator;
52 import java.util.LinkedList;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Properties;
56 import java.util.Set;
57 import java.util.UUID;
58
59 import javax.crypto.Cipher;
60 import javax.crypto.spec.SecretKeySpec;
61 import javax.persistence.EntityManager;
62 import javax.persistence.EntityManagerFactory;
63 import javax.persistence.LockModeType;
64 import javax.persistence.PersistenceException;
65 import javax.persistence.Query;
66 import javax.persistence.RollbackException;
67 import javax.xml.parsers.DocumentBuilder;
68 import javax.xml.parsers.DocumentBuilderFactory;
69 import javax.xml.xpath.XPath;
70 import javax.xml.xpath.XPathFactory;
71
72 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
73
74 import org.apache.commons.io.FileUtils;
75 import org.apache.commons.io.FilenameUtils;
76 import org.apache.commons.io.IOUtils;
77 import org.openecomp.policy.common.logging.eelf.MessageCodes;
78 import org.openecomp.policy.common.logging.eelf.PolicyLogger;
79 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
80 import org.openecomp.policy.common.logging.flexlogger.Logger;
81 import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet;
82 import org.openecomp.policy.rest.XACMLRestProperties;
83 import org.openecomp.policy.rest.adapter.PolicyRestAdapter;
84 import org.openecomp.policy.rest.jpa.ActionBodyEntity;
85 import org.openecomp.policy.rest.jpa.ConfigurationDataEntity;
86 import org.openecomp.policy.rest.jpa.DatabaseLockEntity;
87 import org.openecomp.policy.rest.jpa.GroupEntity;
88 import org.openecomp.policy.rest.jpa.PdpEntity;
89 import org.openecomp.policy.rest.jpa.PolicyDBDaoEntity;
90 import org.openecomp.policy.rest.jpa.PolicyEntity;
91 import org.openecomp.policy.rest.jpa.PolicyVersion;
92 import org.openecomp.policy.rest.util.Webapps;
93 import org.openecomp.policy.xacml.api.pap.EcompPDP;
94 import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
95 import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine;
96 import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
97 import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
98 import org.openecomp.policy.xacml.util.XACMLPolicyScanner;
99 import org.openecomp.policy.xacml.util.XACMLPolicyWriter;
100 import org.w3c.dom.Document;
101 import org.xml.sax.InputSource;
102
103 import com.att.research.xacml.api.pap.PAPException;
104 import com.att.research.xacml.api.pap.PDP;
105 import com.att.research.xacml.api.pap.PDPPolicy;
106 import com.att.research.xacml.util.XACMLProperties;
107
108 public class PolicyDBDao {
109         private static final Logger logger      = FlexLogger.getLogger(PolicyDBDao.class);              
110         private List<?> otherServers;
111         private EntityManagerFactory emf;
112         private static PolicyDBDao currentInstance = null;
113         private PAPPolicyEngine papEngine;
114
115         public static final String JSON_CONFIG = "JSON";
116         public static final String XML_CONFIG = "XML";
117         public static final String PROPERTIES_CONFIG = "PROPERTIES";
118         public static final String OTHER_CONFIG = "OTHER";
119         public static final String AUDIT_USER = "audit";
120
121         /**
122          * Get an instance of a PolicyDBDao. It creates one if it does not exist.
123          * Only one instance is allowed to be created per server.
124          * @param emf The EntityFactoryManager to be used for database connections
125          * @return The new instance of PolicyDBDao or throw exception if the given emf is null.
126          * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this.
127          */
128         public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) throws Exception{
129                 logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called");
130                 if(currentInstance == null){
131                         if(emf != null){
132                                 currentInstance = new PolicyDBDao(emf);
133                                 return currentInstance;
134                         }
135                         throw new IllegalStateException("The EntityManagerFactory is Null");
136                 }
137                 return currentInstance;
138         }
139
140         /**
141          * Gets the current instance of PolicyDBDao. 
142          * @return The instance of PolicyDBDao or throws exception if the given instance is null.
143          * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this.
144          */
145         public static PolicyDBDao getPolicyDBDaoInstance() throws Exception{
146                 logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called");
147                 if(currentInstance != null){
148                         return currentInstance;
149                 }
150                 throw new IllegalStateException("The PolicyDBDao.currentInstance is Null.  Use getPolicyDBDao(EntityManagerFactory emf)");
151         }
152         public void setPapEngine(PAPPolicyEngine papEngine2){
153                 this.papEngine = (PAPPolicyEngine) papEngine2;
154         }
155         private PolicyDBDao(EntityManagerFactory emf){
156                 logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao("+emf+") called");
157                 this.emf = emf;
158
159                 //not needed in this release
160                 if(!register()){
161                         PolicyLogger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
162                 }
163
164                 otherServers = getRemotePolicyDBDaoList();
165                 if(logger.isDebugEnabled()){
166                         logger.debug("Number of remote PolicyDBDao instances: "+otherServers.size());
167                 }
168                 if(otherServers.size() < 1){
169                         logger.warn("List of PolicyDBDao servers is empty or could not be retrieved");
170                 }
171         }
172
173         //not static because we are going to be using the instance's emf
174         //waitTime in ms to wait for lock, or -1 to wait forever (no)
175         private void startTransactionSynced(EntityManager entityMgr,int waitTime){
176                 logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as "
177                                 + "\n   startTransactionSynced("+entityMgr+","+waitTime+") called\n\n");
178                 DatabaseLockEntity lock = null;         
179
180                 entityMgr.setProperty("javax.persistence.query.timeout", waitTime);
181                 entityMgr.getTransaction().begin();
182
183                 if(logger.isDebugEnabled()){
184                         Map<String,Object> properties = entityMgr.getProperties();
185                         logger.debug("\n\nstartTransactionSynced():"
186                                         + "\n   entityManager.getProperties() = " + properties 
187                                         + "\n\n");
188                 }
189                 try{
190                         if(logger.isDebugEnabled()){
191                                 logger.debug("\n\nstartTransactionSynced():"
192                                                 + "\n   ATTEMPT to get the DB lock"
193                                                 + "\n\n");
194                         }
195                         lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE);
196                         if(logger.isDebugEnabled()){
197                                 logger.debug("\n\nstartTransactionSynced():"
198                                                 + "\n   GOT the DB lock"
199                                                 + "\n\n");
200                         }
201                 } catch(Exception e){
202                         System.out.println("Could not get lock entity");
203                         logger.error("Exception Occured"+e);
204                 }
205                 if(lock == null){
206                         throw new IllegalStateException("The lock row does not exist in the table. Please create a primary key with value = 1.");       
207                 }
208
209         }
210         /**
211          * Gets the list of other registered PolicyDBDaos from the database
212          * @return List (type PolicyDBDaoEntity) of other PolicyDBDaos
213          */
214         private List<?> getRemotePolicyDBDaoList(){
215                 logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called");
216                 List<?> policyDBDaoEntityList = new LinkedList<>();
217                 EntityManager em = emf.createEntityManager();
218                 startTransactionSynced(em, 1000);
219                 try{                                            
220                         Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll");                     
221                         policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList();
222
223                 } catch(Exception e){
224                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception querying for other registered PolicyDBDaos");
225                         logger.warn("List of remote PolicyDBDaos will be empty");
226                 }
227                 try{
228                         em.getTransaction().commit();
229                 } catch(Exception e){
230                         try{
231                                 em.getTransaction().rollback();
232                         } catch(Exception e2){
233
234                         }
235                 }
236                 em.close();
237                 return policyDBDaoEntityList;
238         }
239
240         public PolicyDBDaoTransaction getNewTransaction(){
241                 logger.debug("getNewTransaction() as getNewTransaction() called");
242                 return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance());
243         }
244
245         /*
246          * Because the normal transactions are not used in audits, we can use the same transaction
247          * mechanism to get a transaction and obtain the emlock and the DB lock.  We just need to
248          * provide different transaction timeout values in ms because the audit will run longer
249          * than normal transactions.
250          */
251         public PolicyDBDaoTransaction getNewAuditTransaction(){
252                 logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called");
253                 //Use the standard transaction wait time in ms
254                 int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
255                 //Use the (extended) audit timeout time in ms
256                 int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); 
257                 return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs));
258         }
259
260
261         /**
262          * Checks if two strings are equal. Null strings ARE allowed.
263          * @param one A String or null to compare
264          * @param two A String or null to compare
265          */
266         private static boolean stringEquals(String one, String two){
267                 logger.debug("stringEquals(String one, String two) as stringEquals("+one+", "+two+") called");
268                 if(one == null && two == null){
269                         return true;
270                 }
271                 if(one == null || two == null){
272                         return false;
273                 }
274                 return one.equals(two);
275         }
276
277         /**
278          * Computes the scope in dotted format based on an absolute path and a path that divides the scope.
279          * @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)
280          * @param pathToExclude The path that acts as a division between the scope and the other folders
281          * @return The scope in dotted format (org.openecomp)
282          */
283         private static String computeScope(String fullPath, String pathToExclude){
284                 logger.debug("computeScope(String fullPath, String pathToExclude) as computeScope("+fullPath+", "+pathToExclude+") called");
285                 int excludeIndex = fullPath.indexOf(pathToExclude);
286                 String scopePath = fullPath.substring(excludeIndex+pathToExclude.length());
287                 String scope = scopePath.replace('\\', '.');
288                 scope = scope.replace('/', '.');
289                 if(scope.charAt(0) == '.'){
290                         scope = scope.substring(1);
291                 }
292                 if(scope.charAt(scope.length()-1) == '.'){
293                         scope = scope.substring(0, scope.length()-1);
294                 }
295                 return scope;
296         }
297
298         /**
299          * Returns the url of this local pap server, removing the username and password, if they are present
300          * @return The url of this local pap server
301          */
302         private String[] getPapUrlUserPass(){
303                 logger.debug("getPapUrl() as getPapUrl() called");
304                 String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
305                 if(url == null){
306                         return null;
307                 }
308                 return splitPapUrlUserPass(url);
309
310
311         }
312         private String[] splitPapUrlUserPass(String url){
313                 String[] urlUserPass = new String[3];
314                 String[] commaSplit = url.split(",");
315                 urlUserPass[0] = commaSplit[0];
316                 if(commaSplit.length > 2){
317                         urlUserPass[1] = commaSplit[1];
318                         urlUserPass[2] = commaSplit[2];
319                 }
320                 if(urlUserPass[1] == null || urlUserPass[1].equals("")){
321                         String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
322                         if(usernamePropertyValue != null){
323                                 urlUserPass[1] = usernamePropertyValue;
324                         }
325                 }
326                 if(urlUserPass[2] == null || urlUserPass[2].equals("")){
327                         String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
328                         if(passwordPropertyValue != null){
329                                 urlUserPass[2] = passwordPropertyValue;
330                         }
331                 }
332                 //if there is no comma, for some reason there is no username and password, so don't try to cut them off
333                 return urlUserPass;
334         }
335
336         private static String encryptPassword(String password) throws Exception{
337                 Cipher cipher = Cipher.getInstance("AES");              
338                 cipher.init(Cipher.ENCRYPT_MODE, aesKey());
339                 byte[] encryption = cipher.doFinal(password.getBytes("UTF-8"));
340                 System.out.println(encryption);
341                 return new String(Base64.getMimeEncoder().encode(encryption),"UTF-8");
342         }
343
344         private static String decryptPassword(String encryptedPassword) throws Exception{
345                 Cipher cipher = Cipher.getInstance("AES");
346                 cipher.init(Cipher.DECRYPT_MODE, aesKey());
347                 byte[] password = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword.getBytes("UTF-8")));
348                 return new String(password,"UTF-8");
349         }
350         private static Key aesKey(){
351                 byte[] aesValue = (new String("njrmbklcxtoplawf")).getBytes();
352                 return new SecretKeySpec(aesValue,"AES");
353         }
354         /**
355          * Register the PolicyDBDao instance in the PolicyDBDaoEntity table
356          * @return Boolean, were we able to register?
357          */
358         private boolean register(){
359                 logger.debug("register() as register() called");
360                 String[] url = getPapUrlUserPass();
361                 EntityManager em = emf.createEntityManager();
362                 try{
363                         startTransactionSynced(em, 1000);
364                 } catch(IllegalStateException e){
365                         logger.debug ("\nPolicyDBDao.register() caught an IllegalStateException: \n" +e + "\n");
366                         DatabaseLockEntity lock;
367                         lock = em.find(DatabaseLockEntity.class, 1);
368                         if(lock==null){                         
369                                 lock = new DatabaseLockEntity();
370                                 em.persist(lock);
371                                 lock.setKey(1);
372                                 try{
373                                         em.flush();
374                                         em.getTransaction().commit();
375                                         em.close();                                     
376                                 } catch(Exception e2){
377                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "COULD NOT CREATE DATABASELOCK ROW.  WILL TRY ONE MORE TIME");
378                                 }
379                                 em = null;
380                                 em = emf.createEntityManager();
381                                 try{
382                                         startTransactionSynced(em, 1000);
383                                 } catch(Exception e3){
384                                         String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING";
385                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, "PolicyDBDao", msg);
386                                         throw new IllegalStateException("msg" + "\n" + e3);
387                                 }
388                         }
389                 }
390                 logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n");
391                 PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]);
392                 Query getPolicyDBDaoEntityQuery = em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url");
393                 getPolicyDBDaoEntityQuery.setParameter("url", url[0]);
394                 if(foundPolicyDBDaoEntity == null){
395                         PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity();
396                         em.persist(newPolicyDBDaoEntity);
397                         newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]);
398                         newPolicyDBDaoEntity.setDescription("PAP server at "+url[0]);
399                         newPolicyDBDaoEntity.setUsername(url[1]);
400                         try{
401                                 newPolicyDBDaoEntity.setPassword(encryptPassword(url[2]));
402                         } catch(Exception e){
403                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
404                         }
405                         try{
406                                 em.getTransaction().commit();
407                         } catch(Exception e){
408                                 try{
409                                         em.getTransaction().rollback();
410                                 } catch(Exception e2){
411                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not add new PolicyDBDao to the database");
412                                 }
413                         }
414                 } else {
415                         //just want to update in order to change modified date
416                         String encryptedPassword = null;
417                         try{
418                                 encryptedPassword = encryptPassword(url[2]);
419                         } catch(Exception e){
420                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
421                         }
422                         if(url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())){
423                                 foundPolicyDBDaoEntity.setUsername(url[1]);
424                         }
425                         if(encryptedPassword != null && !stringEquals(encryptedPassword, foundPolicyDBDaoEntity.getPassword())){
426                                 foundPolicyDBDaoEntity.setPassword(encryptedPassword);
427                         }
428                         foundPolicyDBDaoEntity.preUpdate();
429                         try{
430                                 em.getTransaction().commit();
431                         } catch(Exception e){
432                                 try{
433                                         em.getTransaction().rollback();
434                                 } catch(Exception e2){
435                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not update PolicyDBDao in the database");
436                                 }
437                         }
438                 }
439                 em.close();
440                 logger.debug("\nPolicyDBDao.register(). Success!!\n");
441                 return true;
442         }
443         public void notifyOthers(long entityId,String entityType){
444                 notifyOthers(entityId,entityType,null);
445         }
446         public void notifyOthers(long entityId, String entityType, String newGroupId){
447                 logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers("+entityId+","+entityType+","+newGroupId+") called");             
448                 LinkedList<Thread> notifyThreads = new LinkedList<>();
449
450                 //we're going to run notiftions in parellel threads to speed things up
451                 for(Object obj : otherServers){
452
453                         Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId));
454
455                         newNotifyThread.start();
456
457                         notifyThreads.add(newNotifyThread);
458
459                 }
460                 //we want to wait for all notifications to complete or timeout before we unlock the interface and allow more changes
461                 for(Thread t : notifyThreads){
462                         try {
463                                 t.join();
464                         } catch (Exception e) {
465                                 logger.warn("Could not join a notifcation thread");
466                         }
467                 }
468
469
470         }
471
472         private class NotifyOtherThread implements Runnable {
473                 public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId){
474                         this.obj = obj;
475                         this.entityId = entityId;
476                         this.entityType = entityType;
477                         this.newGroupId = newGroupId;
478                 }
479                 private Object obj;
480                 private long entityId;
481                 private String entityType;
482                 private String newGroupId;
483                 @Override
484                 public void run(){
485                         //naming of 'o' is for backwards compatibility with the rest of the function
486                         PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity)obj;
487                         String o = dbdEntity.getPolicyDBDaoUrl();
488                         String username = dbdEntity.getUsername();
489                         String password;
490                         try{
491                                 password = decryptPassword(dbdEntity.getPassword());
492                         } catch(Exception e){
493                                 //if we can't decrypt, might as well try it anyway
494                                 password = dbdEntity.getPassword();
495                         }
496                         Base64.Encoder encoder = Base64.getEncoder();                   
497                         String encoding = encoder.encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
498                         HttpURLConnection connection = null;
499                         UUID requestID = UUID.randomUUID();
500                         URL url;
501                         try {
502                                 String papUrl = getPapUrlUserPass()[0];
503                                 if(papUrl == null){
504                                         papUrl = "undefined";
505                                 }
506                                 logger.debug("We are going to try to notify "+o);
507                                 //is this our own url?
508                                 String ourUrl = o;
509                                 try{
510                                         ourUrl = splitPapUrlUserPass((String)o)[0];
511                                 }catch(Exception e){
512                                         ourUrl = o;
513                                 }
514                                 if(o == null){
515                                         o = "undefined";
516                                 }
517                                 if(papUrl.equals(ourUrl)){
518                                         logger.debug(((String)o)+" is our url, skipping notify");
519                                         return;
520                                 }
521                                 if(newGroupId == null){
522                                         url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType);
523                                 } else {
524                                         url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType+"&extradata="+newGroupId);
525                                 }
526                         } catch (MalformedURLException e) {
527                                 logger.warn("Caught MalformedURLException on: new URL()", e);
528                                 return;
529                         }
530                         //
531                         // Open up the connection
532                         //
533                         logger.debug("Connecting with url: "+url);
534                         try {
535                                 connection = (HttpURLConnection)url.openConnection();
536                         } catch (Exception e) {
537                                 logger.warn("Caught exception on: url.openConnection()",e);
538                                 return;
539                         }
540                         //
541                         // Setup our method and headers
542                         //
543                         try {
544                                 connection.setRequestMethod("PUT");
545                         } catch (ProtocolException e) {
546                                 //why would this error ever occur?
547                                 logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");",e);                     
548                                 return;
549                         }
550                         connection.setRequestProperty("Authorization", "Basic " + encoding);
551                         connection.setRequestProperty("Accept", "text/x-java-properties");
552                         connection.setRequestProperty("Content-Type", "text/x-java-properties");                                        
553                         connection.setRequestProperty("requestID", requestID.toString());
554                         int readTimeout;
555                         try{
556                                 readTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT));
557
558                         } catch(Exception e){
559                                 logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default.");
560                                 readTimeout = 10000;
561                         }
562                         connection.setReadTimeout(readTimeout);
563                         connection.setConnectTimeout(readTimeout);
564                         connection.setUseCaches(false);
565                         //
566                         // Adding this in. It seems the HttpUrlConnection class does NOT
567                         // properly forward our headers for POST re-direction. It does so
568                         // for a GET re-direction.
569                         //
570                         // So we need to handle this ourselves.
571                         //
572                         connection.setInstanceFollowRedirects(false);
573                         connection.setDoOutput(true);
574                         connection.setDoInput(true);
575                         try {
576                                 connection.connect();
577                         } catch (Exception e) {
578                                 logger.warn("Caught exception on: connection.connect()",e);
579                                 return;
580                         }
581                         try {
582                                 if (connection.getResponseCode() == 200) {
583                                         logger.info("Received response 200 from pap server on notify");
584                                         //notified = true;
585                                 } else {
586                                         logger.warn("connection response code not 200, received: "+connection.getResponseCode());
587                                 }
588                         } catch (Exception e) {
589                                 logger.warn("Caught Exception on: connection.getResponseCode() ", e);
590                         }
591
592
593                         connection.disconnect();
594                 }
595         }
596
597         private static String getElementFromXMLString(String element, String xml) {
598                 InputSource source = new InputSource(new StringReader(xml));
599
600                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
601                 String description = "";
602                 try{
603                         DocumentBuilder db = dbf.newDocumentBuilder();
604                         Document document = db.parse(source);
605
606                         XPathFactory xpathFactory = XPathFactory.newInstance();
607                         XPath xpath = xpathFactory.newXPath();
608
609                         if (element.endsWith("/")){
610                                 element = element.substring(0, element.length() -1);
611                         }
612
613                         description = xpath.evaluate("/Policy" + element + "/text()", document);                
614                 }catch(Exception e){
615
616                 }
617
618
619                 System.out.println("description_" + description);
620                 return description;
621         }
622         private static String evaluateXPath(String expression, String xml) {
623                 InputSource source = new InputSource(new StringReader(xml));
624
625                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
626                 String description = "";
627                 try{
628                         DocumentBuilder db = dbf.newDocumentBuilder();
629                         Document document = db.parse(source);
630
631                         XPathFactory xpathFactory = XPathFactory.newInstance();
632                         XPath xpath = xpathFactory.newXPath();
633
634
635                         description = xpath.evaluate(expression, document);             
636                 }catch(Exception e){
637
638                 }
639
640
641                 System.out.println("description_" + description);
642                 return description;
643         }
644
645         private static String getDescriptionFromXacml(String xacmlData){
646                 String openTag = "<Description>";
647                 String closeTag = "</Description>";
648                 int descIndex = xacmlData.indexOf(openTag);
649                 int endDescIndex = xacmlData.indexOf(closeTag);
650                 String desc = xacmlData.substring(descIndex+openTag.length(),endDescIndex);
651                 return desc;
652         }
653         
654         private final String POLICY_NOTIFICATION = "policy";
655         private final String PDP_NOTIFICATION = "pdp";
656         private final String GROUP_NOTIFICATION = "group";
657         public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, XACMLPapServlet xacmlPapServlet){
658                 logger.info("DBDao url: " + url + " has reported an update on "+entityType+" entity "+entityId);                
659                 PolicyDBDaoTransaction transaction = this.getNewTransaction();
660                 //although its named retries, this is the total number of tries
661                 int retries;
662                 try{
663                         retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INCOMINGNOTIFICATION_TRIES));
664
665                 } catch(Exception e){
666                         logger.error("xacml.rest.pap.incomingnotification.tries property not set, using a default of 3.");
667                         retries = 3;
668                 }
669                 //if someone sets it to some dumb value, we need to make sure it will try at least once
670                 if(retries < 1){
671                         retries = 1;
672                 }
673                 int pauseBetweenRetries = 1000;
674                 switch(entityType){     
675
676                 case POLICY_NOTIFICATION:
677                         for(int i=0; i<retries;i++){
678                                 try{
679                                         handleIncomingPolicyChange(url, entityId,extraData);
680                                         break;
681                                 } catch(Exception e){
682                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")");
683                                 }
684                                 try{
685                                         Thread.sleep(pauseBetweenRetries);
686                                 }catch(InterruptedException ie){
687                                         break;
688                                 }
689                         }
690                         break;
691                 case PDP_NOTIFICATION:
692                         for(int i=0; i<retries;i++){
693                                 try{
694                                         handleIncomingPdpChange(url, entityId, transaction);
695                                         break;
696                                 } catch(Exception e){
697                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")");
698                                 }
699                                 try{
700                                         Thread.sleep(pauseBetweenRetries);
701                                 }catch(InterruptedException ie){
702                                         break;
703                                 }
704                         }
705                         break;
706                 case GROUP_NOTIFICATION:
707                         for(int i=0; i<retries;i++){
708                                 try{
709                                         handleIncomingGroupChange(url, entityId, extraData, transaction, xacmlPapServlet);
710                                         break;
711                                 }catch(Exception e){
712                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")");
713                                 }
714                                 try{
715                                         Thread.sleep(pauseBetweenRetries);
716                                 }catch(InterruptedException ie){
717                                         break;
718                                 }
719                         }
720                         break;          
721                 }
722                 //no changes should be being made in this function, we still need to close
723                 transaction.rollbackTransaction();
724         }
725         private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException{
726                 GroupEntity groupRecord = null;
727                 long groupIdLong = -1;
728                 try{
729                         groupIdLong = Long.parseLong(groupId);
730                 } catch(NumberFormatException e){
731                         throw new IllegalArgumentException("groupId "+groupId+" cannot be parsed into a long");
732                 }
733                 try{
734                         groupRecord = transaction.getGroup(groupIdLong);
735                 } catch(Exception e){
736                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");");
737                         throw new PAPException("Could not get local group "+groupIdLong);
738                 }
739                 if(groupRecord == null){
740                         throw new PersistenceException("The group record returned is null");
741                 }
742                 //compare to local fs
743                 //does group folder exist
744                 EcompPDPGroup localGroup = null;
745                 try {
746                         localGroup = papEngine.getGroup(groupRecord.getGroupId());
747                 } catch (Exception e) {
748                         logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+groupId+");",e);
749                 }
750                 if(localGroup == null && extraData != null){
751                         //here we can try to load an old group id from the extraData
752                         try{
753                                 localGroup = papEngine.getGroup(extraData);
754                         }catch(Exception e){
755                                 logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+extraData+");",e);
756                         }
757                 }
758                 if(localGroup != null && groupRecord.isDeleted()){
759                         EcompPDPGroup newLocalGroup = null;
760                         if(extraData != null){
761                                 try {
762                                         newLocalGroup = papEngine.getGroup(extraData);
763                                 } catch (PAPException e) {
764                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");");
765                                 }
766                         }
767                         try {
768                                 papEngine.removeGroup(localGroup, newLocalGroup);
769                         } catch (NullPointerException | PAPException e) {
770                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");");
771                                 throw new PAPException("Could not remove group "+groupId);
772                         }
773                 }
774                 else if(localGroup == null){
775                         //creating a new group
776                         try {
777                                 papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());
778                         } catch (NullPointerException | PAPException e) {
779                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());");
780                                 throw new PAPException("Could not create group "+groupRecord);
781                         }
782                         try {
783                                 localGroup = papEngine.getGroup(groupRecord.getGroupId());
784                         } catch (PAPException e1) {
785                                 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");
786                                 return;
787                         }
788                         //add possible pdps to group
789                         List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId()));
790                         for(Object pdpO : pdpsInGroup){
791                                 PdpEntity pdp = (PdpEntity)pdpO;
792                                 try {
793                                         papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());
794                                 } catch (NullPointerException | PAPException e) {
795                                         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());");
796                                         throw new PAPException("Could not create pdp "+pdp);
797                                 }
798                         }
799                         //add possible policies to group (filesystem only, apparently)
800                 } else {
801                         if(!(localGroup instanceof StdPDPGroup)){
802                                 throw new PAPException("group is not a StdPDPGroup");
803                         }
804                         //clone the object
805                         //because it will be comparing the new group to its own version
806                         StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(),localGroup.isDefaultGroup(),localGroup.getName(),localGroup.getDescription(),((StdPDPGroup)localGroup).getDirectory());
807                         localGroupClone.setEcompPdps(localGroup.getEcompPdps());
808                         localGroupClone.setPipConfigs(localGroup.getPipConfigs());
809                         localGroupClone.setStatus(localGroup.getStatus());                      
810                         //we are updating a group or adding a policy or changing default
811                         //set default if it should be
812                         if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){
813                                 try {
814                                         papEngine.SetDefaultGroup(localGroup);
815                                         return;
816                                 } catch (PAPException e) {
817                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");");
818                                         throw new PAPException("Could not set default group to "+localGroupClone);
819                                 }                               
820                         }               
821                         boolean needToUpdate = false;
822                         if(updateGroupPoliciesInFileSystem(localGroupClone,localGroup, groupRecord, transaction)){
823                                 needToUpdate = true;
824                         }
825                         if(!stringEquals(localGroupClone.getId(),groupRecord.getGroupId()) || !stringEquals(localGroupClone.getName(),groupRecord.getgroupName())){
826                                 //changing ids
827                                 //we do not want to change the id, the papEngine will do this for us, it needs to know the old id
828                                 localGroupClone.setName(groupRecord.getgroupName());
829                                 needToUpdate = true;
830                         }
831                         if(!stringEquals(localGroupClone.getDescription(),groupRecord.getDescription())){
832                                 localGroupClone.setDescription(groupRecord.getDescription());
833                                 needToUpdate = true;
834                         }
835                         if(needToUpdate){
836                                 try {
837
838                                         papEngine.updateGroup(localGroupClone);
839                                 } catch (PAPException e) {
840                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");");
841                                         throw new PAPException("Could not update group "+localGroupClone);
842                                 }
843                         }                               
844
845                 }
846                 //call command that corresponds to the change that was made
847         }
848         //this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db
849         private boolean updateGroupPoliciesInFileSystem(EcompPDPGroup pdpGroup,EcompPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException{
850                 if(!(pdpGroup instanceof StdPDPGroup)){
851                         throw new PAPException("group is not a StdPDPGroup");
852                 }
853                 StdPDPGroup group = (StdPDPGroup)pdpGroup;
854                 //this must always be true since we don't explicitly know when a delete is occuring
855                 boolean didUpdate = true;
856                 HashMap<String,PDPPolicy> currentPolicySet = new HashMap<String,PDPPolicy>(oldPdpGroup.getPolicies().size());
857                 HashSet<PDPPolicy> newPolicySet = new HashSet<>();
858                 for(PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()){
859                         currentPolicySet.put(pdpPolicy.getId(), pdpPolicy);
860                 }
861                 for(PolicyEntity policy : groupRecord.getPolicies()){
862                         String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
863                         if(group.getPolicy(pdpPolicyName) == null){
864                                 didUpdate = true;
865                                 if(currentPolicySet.containsKey(pdpPolicyName)){
866                                         newPolicySet.add(currentPolicySet.get(pdpPolicyName));
867                                 } else{
868                                         InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
869                                         group.copyPolicyToFile(pdpPolicyName,policyStream);
870                                         ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(policy.getPolicyName()));
871                                         try {
872                                                 policyStream.close();
873                                         } catch (IOException e) {
874                                                 PolicyLogger.error(e.getMessage());
875                                         }
876                                 }
877                         }
878                 }
879                 if(didUpdate){
880                         newPolicySet.addAll(group.getPolicies());
881                         group.setPolicies(newPolicySet);
882                 }
883                 return didUpdate;
884
885         }
886         private String removeExtensionAndVersionFromPolicyName(String originalPolicyName){
887         return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0];
888     }
889
890     /**
891      * Splits apart the policy name and version from a policy file path
892      * @param originalPolicyName: a policy file name ex: Config_policy.2.xml
893      * @return An array [0]: The policy name, [1]: the policy version, as a string
894      */
895     private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){
896         String policyName = originalPolicyName;
897         String[] nameAndVersion = new String[2];
898         try{
899             policyName = removeFileExtension(policyName);
900             nameAndVersion[0] = policyName.substring(0,policyName.lastIndexOf('.'));
901             if(isNullOrEmpty(nameAndVersion[0])){
902                 throw new Exception();
903             }
904         } catch(Exception e){
905             nameAndVersion[0] = originalPolicyName;         
906         }
907         try{
908             nameAndVersion[1] = policyName.substring(policyName.lastIndexOf('.')+1);
909             if(isNullOrEmpty(nameAndVersion[1])){
910                 throw new Exception();
911             }
912         } catch(Exception e){
913             nameAndVersion[1] = "1";
914         }
915         return nameAndVersion;
916     }
917     
918         private void handleIncomingPdpChange(String url, String pdpId, PolicyDBDaoTransaction transaction) throws PAPException{
919                 //get pdp
920                 long pdpIdLong = -1;
921                 try{
922                         pdpIdLong = Long.parseLong(pdpId);
923                 }catch(NumberFormatException e){
924                         throw new IllegalArgumentException("pdpId "+pdpId+" cannot be parsed into a long");
925                 }
926                 PdpEntity pdpRecord = null;
927                 try{
928                         pdpRecord = transaction.getPdp(pdpIdLong);
929                 }catch(Exception e){
930                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");");
931                         throw new PAPException("Could not get local pdp "+pdpIdLong);
932                 }
933                 if(pdpRecord == null){
934                         throw new PersistenceException("The pdpRecord returned is null");
935                 }
936                 PDP localPdp = null;
937                 try {
938                         localPdp = papEngine.getPDP(pdpRecord.getPdpId());
939                 } catch (PAPException e) {
940                         logger.warn("Caught PAPException trying to get local pdp  with papEngine.getPDP("+pdpId+");",e);
941                 }
942                 if(localPdp != null && pdpRecord.isDeleted()){
943                         try {
944                                 papEngine.removePDP((EcompPDP) localPdp);
945                         } catch (PAPException e) {
946                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");");
947                                 throw new PAPException("Could not remove pdp "+pdpId);
948                         }
949                 }
950                 else if(localPdp == null){
951                         //add new pdp
952                         //get group
953                         EcompPDPGroup localGroup = null;
954                         try {
955                                 localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
956                         } catch (PAPException e1) {
957                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
958                                 throw new PAPException("Could not get local group");
959                         }                       
960                         try {
961                                 papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort());
962                         } catch (NullPointerException | PAPException e) {
963                                 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()+");");
964                                 throw new PAPException("Could not create pdp "+pdpRecord);
965                         }
966                 } else {
967                         boolean needToUpdate = false;
968                         if(!stringEquals(localPdp.getId(),pdpRecord.getPdpId()) || !stringEquals(localPdp.getName(),pdpRecord.getPdpName())){
969                                 //again, we don't want to change the id, the papEngine will do this
970                                 localPdp.setName(pdpRecord.getPdpName());
971                                 needToUpdate = true;
972                         }
973                         if(!stringEquals(localPdp.getDescription(),pdpRecord.getDescription())){
974                                 localPdp.setDescription(pdpRecord.getDescription());
975                                 needToUpdate = true;
976                         }
977                         String localPdpGroupId = null;
978                         try{
979                                 localPdpGroupId = papEngine.getPDPGroup((EcompPDP) localPdp).getId();
980                         } catch(PAPException e){
981                                 //could be null or something, just warn at this point
982                                 logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();",e);
983                         }
984                         if(!stringEquals(localPdpGroupId,pdpRecord.getGroup().getGroupId())){
985                                 EcompPDPGroup newPdpGroup = null;
986                                 try{
987                                         newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
988                                 }catch(PAPException e){
989                                         //ok, now we have an issue. Time to stop things
990                                         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());");
991                                         throw new PAPException("Could not get local group");
992                                 }
993                                 try{
994                                         papEngine.movePDP((EcompPDP) localPdp, newPdpGroup);
995                                 }catch(PAPException e){
996                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);");
997                                         throw new PAPException("Could not move pdp "+localPdp);
998                                 }
999                         }
1000                         if(((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()){
1001                                 ((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort());
1002                                 needToUpdate = true;
1003                         }
1004                         if(needToUpdate){
1005                                 try {
1006                                         papEngine.updatePDP((EcompPDP) localPdp);
1007                                 } catch (PAPException e) {
1008                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");");
1009                                         throw new PAPException("Could not update pdp "+localPdp);
1010                                 }
1011                         }
1012                 }
1013                 //compare to local situation
1014                 //call command to update
1015         }
1016         private void handleIncomingPolicyChange(String url, String policyId,String oldPathString){
1017                 EntityManager em = emf.createEntityManager();
1018                 Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById");
1019                 getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId));
1020
1021                 @SuppressWarnings("unchecked")
1022                 List<PolicyEntity> policies = getPolicyEntityQuery.getResultList();
1023                 PolicyEntity policy = null;
1024                 if (policies.size() > 0){
1025                         policy = policies.get(0);
1026                 }
1027
1028                 String policyRepo = buildPolicyScopeDirectory(policy);
1029
1030                 Path policyPath = Paths.get(policyRepo);
1031                 String action = "unknown action";
1032                 try {
1033
1034                         if(policy.isDeleted()){
1035                                 logger.debug("Deleting Policy: " + policy.getPolicyName());
1036                                 action = "delete";
1037                                 Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName());
1038                                 Files.deleteIfExists(newPath);
1039
1040                                 Path subFile = null;
1041
1042                                 if (policy.getConfigurationData()!= null){
1043                                         subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), "Config");
1044                                 }else if(policy.getActionBodyEntity()!= null){
1045                                         subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), "Action");
1046                                 }
1047
1048                                 if(subFile != null){
1049                                         Files.deleteIfExists(subFile);
1050                                 }
1051
1052                         }else{
1053                                 logger.debug("Updating/Creating Policy: " + policy.getPolicyName());
1054                                 action = "update";
1055                                 Files.createDirectories(policyPath);
1056                                 Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName());
1057                                 Files.deleteIfExists(newPath);
1058                                 if(!isNullOrEmpty(oldPathString)){
1059                                         try{
1060                                                 String[] scopeName = getScopeAndNameAndType(oldPathString);
1061                                                 Path oldPath = Paths.get(buildPolicyScopeDirectory(scopeName[0]),scopeName[1]);
1062                                                 Files.delete(oldPath.toAbsolutePath());
1063                                         }catch(Exception e){
1064                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy before rename: "+oldPathString);
1065                                         }
1066                                 }
1067                                 Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData()));
1068                                 XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData);            
1069
1070                                 if (policy.getConfigurationData()!= null){
1071                                         if(!isNullOrEmpty(oldPathString)){
1072                                                 try{                                            
1073                                                         String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString);
1074                                                         String oldConfigFileName = getConfigFile(oldPolicyScopeName[1],policy.getConfigurationData().getConfigType());
1075                                                         Path oldConfigFilePath = getPolicySubFile(oldConfigFileName, "Config");
1076                                                         logger.debug("Trying to delete: "+oldConfigFilePath.toString());
1077                                                         Files.delete(oldConfigFilePath);                                                
1078                                                 }catch(Exception e){
1079                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy config before rename for policy: "+oldPathString);
1080                                                 }
1081                                         }
1082                                         writePolicySubFile(policy, "Config");
1083
1084                                 }else if(policy.getActionBodyEntity()!= null){
1085                                         if(!isNullOrEmpty(oldPathString)){
1086                                                 try{                                            
1087                                                         String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString);
1088                                                         String oldActionFileName = getConfigFile(oldPolicyScopeName[1],ConfigPolicy.JSON_CONFIG);
1089                                                         Path oldActionFilePath = getPolicySubFile(oldActionFileName, "Action");
1090                                                         logger.debug("Trying to delete: "+oldActionFilePath.toString());
1091                                                         Files.delete(oldActionFilePath);                                                
1092                                                 }catch(Exception e){
1093                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy action body before rename for policy: "+oldPathString);
1094                                                 }
1095                                         }
1096                                         writePolicySubFile(policy, "Action");
1097                                 }
1098
1099                         }
1100                 } catch (IOException e1) {
1101                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while performing [" + action + "] of Policy File: " +  policy.getPolicyName());
1102                 }       
1103         }
1104
1105         private void createGroupsFromDatabase(){
1106                 //get list of groups
1107                 boolean foundDefault = false;
1108                 //need to avoid infinite loop, just in case
1109                 boolean alreadyRunAdd = false;
1110                 while(!foundDefault){                   
1111
1112                         EntityManager em = emf.createEntityManager();
1113                         Query getGroups = em.createQuery("SELECT g FROM GroupEntity g WHERE g.deleted=:deleted");
1114                         getGroups.setParameter("deleted", false);
1115                         List<?> groups = getGroups.getResultList();
1116                         em.close();
1117                         //make a folder for each group in pdps folders
1118                         Path pdpsPath = Paths.get(XACMLProperties.getProperty("xacml.pap.pdps"));
1119                         if(!pdpsPath.toFile().exists()){
1120                                 try {
1121                                         FileUtils.forceMkdir(pdpsPath.toFile());
1122                                 } catch (IOException e) {
1123                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not make the new pdps folder; one does not exist");
1124                                 }
1125                         }
1126                         Properties propertyFileProperties = new Properties();
1127                         String groupList = "";
1128                         String defaultGroup = "";
1129                         HashSet<String> currentGroupPaths = new HashSet<>();
1130                         for(Object o : groups){
1131                                 GroupEntity group = (GroupEntity)o;
1132                                 Path groupPath = Paths.get(pdpsPath.toString(), group.getGroupId());
1133                     currentGroupPaths.add(groupPath.getFileName().toString());
1134                     if(groupPath.toFile().exists()){
1135                         try {
1136                             FileUtils.forceDelete(Paths.get(groupPath.toString(), "xacml.policy.properties").toFile());
1137                         } catch (IOException e) {
1138                             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete old xacml.policy.properties file");
1139                         }
1140                         File[] xmlFiles = groupPath.toFile().listFiles(new FileFilter(){
1141              
1142                             @Override
1143                             public boolean accept(File pathname) {
1144                                 return pathname.toString().endsWith(".xml");
1145                             }
1146                             
1147                         });
1148                         for(File deleteMe : xmlFiles){
1149                             try {
1150                                 FileUtils.forceDelete(deleteMe);
1151                             } catch (IOException e) {
1152                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete one of the policy files that we are going to replace: "+deleteMe.toString());
1153                             }
1154                         }
1155                     } else {
1156                                 try {
1157                                         FileUtils.forceMkdir(groupPath.toFile());
1158                                 } catch (IOException e) {
1159                                         logger.error("Exception Occured"+e);
1160                                 }
1161                         }
1162                                 Properties policyProperties = new Properties();
1163                                 String rootPolicies = "";
1164                                 for(PolicyEntity policy : group.getPolicies()){
1165                                         Path newPolicyPath = Paths.get(groupPath.toString(),getPdpPolicyName(policy.getPolicyName(),policy.getScope()));
1166                                         File newPolicyFile = newPolicyPath.toFile();
1167                                         try {
1168                                                 newPolicyFile.createNewFile();
1169                                         } catch (IOException e) {
1170                                                 PolicyLogger.error(e.getMessage());
1171                                         }
1172                                         try {
1173                                                 FileOutputStream policyFileStream = new FileOutputStream(newPolicyFile);
1174                                                 policyFileStream.write(policy.getPolicyData().getBytes("UTF-8"));
1175                                                 policyFileStream.close();
1176                                         } catch (IOException e) {
1177                                                 PolicyLogger.error(e.getMessage());
1178                                         }
1179                                         policyProperties.setProperty(getPdpPolicyName(policy.getPolicyName(),policy.getScope())+".name",removeExtensionAndVersionFromPolicyName(policy.getPolicyName()));
1180                                         rootPolicies += ",".concat(getPdpPolicyName(policy.getPolicyName(),policy.getScope()));
1181                                 }
1182                                 Path xacmlPolicyPropertiesPath = Paths.get(groupPath.toString(),"xacml.policy.properties");
1183                                 File xacmlPolicyPropertiesFile = xacmlPolicyPropertiesPath.toFile();
1184                                 if(rootPolicies.length() > 0){
1185                                         rootPolicies = rootPolicies.substring(1);
1186                                 }
1187                                 policyProperties.setProperty("xacml.referencedPolicies", "");
1188                                 policyProperties.setProperty("xacml.rootPolicies", rootPolicies);
1189
1190                                 try {
1191                                         xacmlPolicyPropertiesFile.createNewFile();
1192                                 } catch (IOException e) {
1193                                         PolicyLogger.error(e.getMessage());
1194                                 }
1195                                 try {
1196                                         FileOutputStream xacmlPolicyPropertiesFileStream = new FileOutputStream(xacmlPolicyPropertiesFile);
1197                                         policyProperties.store(xacmlPolicyPropertiesFileStream, "");
1198                                         xacmlPolicyPropertiesFileStream.close();
1199                                 } catch (IOException e) {
1200                                         PolicyLogger.error(e.getMessage());
1201                                 }
1202
1203                                 em = emf.createEntityManager();
1204                                 Query getPdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group AND p.deleted=:deleted");
1205                                 getPdpsQuery.setParameter("group", group);
1206                                 getPdpsQuery.setParameter("deleted", false);
1207                                 List<?> pdps = getPdpsQuery.getResultList();
1208                                 em.close();                     
1209                                 String pdpLine = "";
1210                                 for(Object o2 : pdps){
1211                                         PdpEntity pdp = (PdpEntity)o2;
1212                                         pdpLine += ",".concat(pdp.getPdpId());
1213                                         propertyFileProperties.setProperty(pdp.getPdpId()+".description",pdp.getDescription());
1214                                         propertyFileProperties.setProperty(pdp.getPdpId()+".jmxport",String.valueOf(pdp.getJmxPort()));
1215                                         propertyFileProperties.setProperty(pdp.getPdpId()+".name",pdp.getPdpName());
1216                                 }
1217                                 if(pdpLine.length() > 0){
1218                                         pdpLine = pdpLine.substring(1);
1219                                 }
1220                                 propertyFileProperties.setProperty(group.getGroupId()+".description", group.getDescription());
1221                                 propertyFileProperties.setProperty(group.getGroupId()+".name", group.getgroupName());
1222                                 propertyFileProperties.setProperty(group.getGroupId()+".pdps",pdpLine);
1223                                 groupList += ",".concat(group.getGroupId());
1224                                 if(group.isDefaultGroup()){
1225                                         defaultGroup = group.getGroupId();
1226                                         foundDefault = true;
1227                                 }
1228                         }
1229                 //check the list of directories in the pdps folder and make sure none should be deleted
1230                 File[] filesInPdpsFolder = pdpsPath.toFile().listFiles(new FileFilter(){
1231                     @Override
1232                     public boolean accept(File pathname) {
1233                         return pathname.isDirectory();
1234                     }
1235                 });
1236                 for(File f : filesInPdpsFolder){
1237                     if(f.isDirectory()){
1238                         if(!currentGroupPaths.contains(f.toPath().getFileName().toString())){
1239                             try {
1240                                 FileUtils.forceDelete(f);
1241                             } catch (IOException e) {
1242                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete pdp group folder, which has been deleted from the database");
1243                             }
1244                         }
1245                     }
1246                 }
1247                         if(!foundDefault && !alreadyRunAdd){
1248                                 alreadyRunAdd = true;
1249                                 //add default group to db
1250                                 try{
1251                                         em = emf.createEntityManager();
1252                                         em.getTransaction().begin();
1253                                         GroupEntity newDefaultGroup = new GroupEntity();
1254                                         em.persist(newDefaultGroup);
1255                                         newDefaultGroup.setDescription("The default group where new PDP's are put.");
1256                                         newDefaultGroup.setGroupId("default");
1257                                         newDefaultGroup.setGroupName("default");
1258                                         newDefaultGroup.setDefaultGroup(true);
1259                                         newDefaultGroup.setCreatedBy("automaticallyAdded");
1260                                         newDefaultGroup.setModifiedBy("automaticallyAdded");
1261                                         em.flush();
1262                                         em.getTransaction().commit();           
1263                                         continue;
1264                                 } catch(Exception e){
1265                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not add a new default group to the database");
1266                                 }
1267                         }
1268
1269                         Path xacmlPropertiesPath = Paths.get(pdpsPath.toString(),"xacml.properties");
1270                         File xacmlPropertiesFile = xacmlPropertiesPath.toFile();
1271                         if(groupList.length()>0){
1272                                 groupList = groupList.substring(1);
1273                         }
1274                         propertyFileProperties.setProperty("xacml.pap.groups",groupList);
1275                         propertyFileProperties.setProperty("xacml.pap.groups.default",defaultGroup);
1276                 try {
1277                     FileUtils.forceDelete(xacmlPropertiesFile);
1278                 } catch (IOException e) {
1279                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old xacml.properties file");
1280                 }
1281                         try {
1282                                 xacmlPropertiesFile.createNewFile();
1283                         } catch (IOException e) {
1284                                 PolicyLogger.error(e.getMessage());
1285                         }
1286                         try {
1287                                 FileOutputStream xacmlPropertiesFileStream = new FileOutputStream(xacmlPropertiesFile);
1288                                 propertyFileProperties.store(xacmlPropertiesFileStream, "");
1289                                 xacmlPropertiesFileStream.close();
1290                         } catch (IOException e) {
1291                                 PolicyLogger.error(e.getMessage());
1292                         }
1293                         //if we get this far down, something went wrong and we don't want to get stuck in the loop
1294                         foundDefault = true;
1295                 }
1296                 //put policies in group folder
1297                 //create xacml.policy.properties in each folder with list of policies in that folder
1298                 //get list of pdps
1299                 //create xacml.properties with list of groups and pdps and other info
1300         }
1301
1302         private String getPdpPolicyName(String name, String scope){
1303                 String finalName = "";
1304                 finalName += scope;
1305                 finalName += ".";
1306                 finalName += removeFileExtension(name);
1307                 finalName += ".xml";
1308                 return finalName;
1309         }
1310         private String removeFileExtension(String fileName){
1311                 return fileName.substring(0, fileName.lastIndexOf('.'));
1312         }
1313
1314         private String buildPolicyScopeDirectory(PolicyEntity policy){
1315                 String repo = buildPolicyDirectory();
1316
1317                 String policyScope = policy.getScope();
1318                 if(policyScope == null){
1319                         policyScope = "";
1320                         PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
1321                 } else {
1322                         policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator());        
1323                 }
1324                 if(policyScope == null){
1325                         policyScope = "";
1326                         PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank.");
1327                 }
1328                 if(repo == null){
1329                         PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank.");
1330                         repo = "";
1331                 }
1332                 Path returnPath = Paths.get(repo + FileSystems.getDefault().getSeparator() + policyScope);
1333                 if(returnPath !=  null){
1334                         return returnPath.toString();
1335                 } else {
1336                         PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank.");
1337                         return "";
1338                 }
1339
1340
1341         }
1342         private String buildPolicyScopeDirectory(String policyScope){
1343                 String repo = buildPolicyDirectory();           
1344                 policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator());
1345                 return repo + FileSystems.getDefault().getSeparator() + policyScope;
1346
1347         }
1348
1349         private static String buildPolicyDirectory(){
1350                 Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), getDefaultWorkspace());
1351                 Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
1352                 Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
1353
1354                 /*
1355                  * Getting and Setting the parent path for Admin Console use when reading the policy files
1356                  */
1357                 //getting the fullpath of the gitPath and convert to string
1358                 String policyDir = gitPath.toAbsolutePath().toString();
1359
1360
1361                 if(policyDir.contains("\\")){
1362                         policyDir = policyDir.replace("XACML-PAP-REST", "XACML-PAP-ADMIN");
1363                 }else{
1364                         if (policyDir.contains("pap")){
1365                                 policyDir = policyDir.replace("pap", "console");
1366                         }
1367                 }
1368                 logger.debug("policyDir: " + policyDir);
1369                 return policyDir;
1370         }
1371
1372         private Path getPolicySubFile(String filename, String subFileType){
1373                 logger.debug("getPolicySubFile(" + filename + ", " + subFileType + ")");
1374                 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), subFileType);
1375                 File file = null;
1376
1377                 filename = FilenameUtils.removeExtension(filename);
1378
1379                 for(File tmpFile : filePath.toFile().listFiles()){
1380                         if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)){
1381                                 file = tmpFile;
1382                         }
1383                 }
1384
1385                 Path finalPath = null;
1386                 if (file!= null){
1387                         finalPath = Paths.get(file.getAbsolutePath());
1388                 }
1389
1390                 logger.debug("end of getPolicySubFile: " + finalPath);
1391                 return finalPath;       
1392         }
1393
1394         private boolean writePolicySubFile(PolicyEntity policy, String policyType){
1395                 logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + "]");
1396                 String type = null;
1397                 String subTypeName = null;
1398                 String subTypeBody = null;
1399                 if (policyType.equalsIgnoreCase("config")){
1400                         type = "Config";
1401                         subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName());
1402                         subTypeBody = policy.getConfigurationData().getConfigBody();
1403
1404                         String configType = policy.getConfigurationData().getConfigType();
1405
1406
1407                         if (configType != null) {
1408                                 if (configType.equals(JSON_CONFIG)) {
1409                                         subTypeName = subTypeName + ".json";
1410                                 }
1411                                 if (configType.equals(XML_CONFIG)) {
1412                                         subTypeName = subTypeName + ".xml";
1413                                 }
1414                                 if (configType.equals(PROPERTIES_CONFIG)) {
1415                                         subTypeName = subTypeName + ".properties";
1416                                 }
1417                                 if (configType.equals(OTHER_CONFIG)) {
1418                                         subTypeName = subTypeName + ".txt";
1419                                 }
1420                         }
1421
1422                 }else if (policyType.equalsIgnoreCase("action")){
1423                         type = "Action";
1424                         subTypeName = policy.getActionBodyEntity().getActionBodyName();
1425                         subTypeBody = policy.getActionBodyEntity().getActionBody();
1426
1427
1428                 }
1429                 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type);
1430
1431                 if(subTypeBody == null){
1432                         subTypeBody = "";
1433                 }
1434                 boolean success = false;
1435                 try {
1436                         Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName));
1437                         File file = Paths.get(filePath.toString(),subTypeName).toFile();
1438                         file.createNewFile();
1439                         FileWriter fileWriter = new FileWriter(file, false); // false to overwrite
1440                         fileWriter.write(subTypeBody);
1441                         fileWriter.close();
1442                         success = true;
1443
1444                 } catch (Exception e) {
1445                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName());
1446                 }                                       
1447
1448                 return success;
1449
1450         }
1451
1452         private String getPolicySubType(String filename){
1453                 String type = null;
1454
1455                 if (filename != null) {
1456                         if (FilenameUtils.getExtension(filename).equalsIgnoreCase("json")) {
1457                                 type = ConfigPolicy.JSON_CONFIG;
1458                         }
1459                         if (FilenameUtils.getExtension(filename).equalsIgnoreCase("xml")) {
1460                                 type = ConfigPolicy.XML_CONFIG;
1461                         }
1462                         if (FilenameUtils.getExtension(filename).equalsIgnoreCase("properties")) {
1463                                 type = ConfigPolicy.PROPERTIES_CONFIG;
1464                         }
1465                         if (FilenameUtils.getExtension(filename).equalsIgnoreCase("txt")) {
1466                                 type = ConfigPolicy.OTHER_CONFIG;
1467                         }
1468                 }
1469
1470                 return type;
1471
1472         }
1473
1474
1475         private  void convertFileToDBEntry(Path path){
1476                 logger.info("convertFileToDBEntry");
1477
1478                 if(path.toString().contains(".git")){
1479                         return;
1480                 }
1481
1482                 String filename = path.getFileName().toString();
1483                 if (filename.contains(".svnignore")){
1484                         return;
1485                 }
1486
1487                 String[] scopeAndName = getScopeAndNameAndType(path.toString());
1488
1489                 if(scopeAndName == null){
1490                         PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + path.toString() + " is null!");
1491                         return;
1492                 }
1493
1494                 EntityManager em = emf.createEntityManager();
1495                 em.getTransaction().begin();
1496
1497                 PolicyEntity policy = new PolicyEntity();
1498                 em.persist(policy);
1499                 String policyScope = scopeAndName[0];
1500                 String policyName = scopeAndName[1];
1501                 policy.setScope(policyScope);
1502                 policy.setPolicyName(policyName);
1503                 policy.setCreatedBy(AUDIT_USER);
1504                 policy.setModifiedBy(AUDIT_USER);
1505
1506                 String newScope = policyScope.replace(".", File.separator);
1507                 String newName = FilenameUtils.removeExtension(policyName);
1508                 int version = 1;
1509                 try{
1510                         //we want the last index +1 because we don't want the dot
1511                         version = Integer.parseInt(newName.substring(newName.lastIndexOf(".")+1)); 
1512                 } catch(Exception e){
1513                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get the policy version number from "+newName);
1514                 }
1515                 newName = newScope + File.separator + newName.substring(0, newName.lastIndexOf("."));   
1516
1517                 Query query = em.createNamedQuery("PolicyVersion.findByPolicyName");
1518                 query.setParameter("pname", newName);
1519
1520                 List<?> result = query.getResultList();
1521                 PolicyVersion versionEntity = null;
1522
1523                 if (!result.isEmpty()) {
1524                         logger.info("Result is not empty");
1525                         versionEntity = (PolicyVersion) result.get(0);
1526                         int highestVersion = Math.max(versionEntity.getHigherVersion(),version);
1527                         versionEntity.setHigherVersion(highestVersion);
1528                         versionEntity.setActiveVersion(highestVersion);
1529                 }else{
1530                         logger.info("result is empty");
1531                         Calendar calendar = Calendar.getInstance();
1532                         Timestamp createdDate = new Timestamp(calendar.getTime().getTime());
1533
1534                         versionEntity = new PolicyVersion();
1535                         em.persist(versionEntity);
1536                         versionEntity.setPolicyName(newName);
1537                         versionEntity.setHigherVersion(version);
1538                         versionEntity.setActiveVersion(version);
1539                         versionEntity.setCreatedBy(AUDIT_USER);
1540                         versionEntity.setModifiedBy(AUDIT_USER);
1541                         versionEntity.setCreatedDate(createdDate);
1542                         versionEntity.setModifiedDate(createdDate);
1543                 }
1544
1545
1546                 try {
1547                         String policyContent = new String(Files.readAllBytes(path));
1548                         policy.setDescription(getElementFromXMLString("/Description", policyContent));
1549                         policy.setPolicyData(policyContent);
1550                 } catch (IOException e1) {
1551                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData");
1552                         em.getTransaction().rollback();
1553                         em.close();
1554                         return;
1555                 }
1556
1557                 if((scopeAndName[2].equalsIgnoreCase("Config"))){
1558                         String scopeName = scopeAndName[0] + "." + scopeAndName[1];
1559                         Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]);
1560                         try {
1561                                 String content = new String(Files.readAllBytes(subFilePath));
1562                                 String configName = subFilePath.getFileName().toString();
1563                                 ConfigurationDataEntity configData = new ConfigurationDataEntity();
1564                                 em.persist(configData);
1565                                 configData.setConfigurationName(subFilePath.getFileName().toString());
1566                                 configData.setConfigBody(content);
1567                                 configData.setConfigType(getPolicySubType(configName));
1568                                 configData.setCreatedBy(AUDIT_USER);
1569                                 configData.setModifiedBy(AUDIT_USER);
1570                                 policy.setConfigurationData(configData);
1571
1572                         } catch (Exception e) {
1573                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Config policy");
1574                                 em.getTransaction().rollback();
1575                                 em.close();
1576                                 return;
1577                         }
1578                 }else if(scopeAndName[2].equalsIgnoreCase("Action")){
1579                         String scopeName = scopeAndName[0] + "." + scopeAndName[1];
1580                         Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]);
1581                         try {
1582                                 String content = new String(Files.readAllBytes(subFilePath));
1583                                 ActionBodyEntity actionBody = new ActionBodyEntity();
1584                                 em.persist(actionBody);
1585                                 actionBody.setActionBodyName(subFilePath.getFileName().toString());
1586                                 actionBody.setActionBody(content);
1587                                 actionBody.setCreatedBy(AUDIT_USER);
1588                                 actionBody.setModifiedBy(AUDIT_USER);
1589                                 policy.setActionBodyEntity(actionBody);
1590
1591                         } catch (Exception e) {
1592                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Action policy");
1593                                 em.getTransaction().rollback();
1594                                 em.close();
1595                                 return;
1596                         }                       
1597                 }
1598                 logger.debug("convertFileToDBEntry commit transaction");
1599                 em.getTransaction().commit();
1600                 em.close();
1601         }
1602
1603         private void deleteAllPolicyTables(){
1604                 EntityManager em = emf.createEntityManager();
1605                 em.getTransaction().begin();
1606                 Query deletePolicyEntityTableUpdate = em.createNamedQuery("PolicyEntity.deleteAll");
1607                 Query deleteActionBodyEntityTableUpdate = em.createNamedQuery("ActionBodyEntity.deleteAll");
1608                 Query deleteConfigurationDataEntityTableUpdate = em.createNamedQuery("ConfigurationDataEntity.deleteAll");
1609                 Query deletePolicyVersionEntityTableUpdate = em.createNamedQuery("PolicyVersion.deleteAll");
1610                 deletePolicyEntityTableUpdate.executeUpdate();
1611                 deleteActionBodyEntityTableUpdate.executeUpdate();
1612                 deleteConfigurationDataEntityTableUpdate.executeUpdate();
1613                 deletePolicyVersionEntityTableUpdate.executeUpdate();
1614                 em.getTransaction().commit();
1615                 em.close();
1616
1617         }
1618
1619         public void auditLocalDatabase(PAPPolicyEngine papEngine2){
1620                 logger.debug("PolicyDBDao.auditLocalDatabase() is called");
1621                 Path webappsPath = Paths.get(buildPolicyDirectory());
1622                 try{
1623                         deleteAllGroupTables();
1624                         deleteAllPolicyTables();
1625                         Files.createDirectories(webappsPath);
1626                         Files.walk(webappsPath).filter(Files::isRegularFile).forEach(this::convertFileToDBEntry);
1627                         auditGroups(papEngine2);
1628                 } catch(Exception e){
1629                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "auditLocalDatabase() error");
1630                         logger.error("Exception Occured"+e);
1631                 }               
1632         }
1633
1634         /**
1635          * Audits and loads the local file system to match the database version.
1636          */
1637         @SuppressWarnings("unchecked")
1638         public void auditLocalFileSystem(){
1639                 logger.debug("PolicyDBDau.auditLocalFileSystem() is called");
1640
1641                 Path webappsPath = Paths.get(buildPolicyDirectory());
1642                 Path configFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Config");
1643                 Path actionFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Action");
1644                 try {
1645                         Files.createDirectories(configFilesPath);
1646                         Files.createDirectories(actionFilesPath);
1647                         FileUtils.cleanDirectory(actionFilesPath.toFile());
1648                         FileUtils.cleanDirectory(configFilesPath.toFile());
1649                         if (webappsPath.toFile().exists()){
1650                                 FileUtils.cleanDirectory(webappsPath.toFile());
1651                         }
1652                         Path repoWithScope = Paths.get(webappsPath.toString(), XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DOMAIN));
1653                         Files.createDirectories(repoWithScope);
1654                 } catch (IOException e2) {
1655                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Error occurred while creating / clearing Config and Policy filesystem directories");
1656                 }
1657
1658                 List<PolicyEntity> policyEntityList;
1659                 try{
1660                         EntityManager em = emf.createEntityManager();
1661                         Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findAllByDeletedFlag");
1662                         getPolicyEntitiesQuery.setParameter("deleted", false);
1663                         policyEntityList = getPolicyEntitiesQuery.getResultList();
1664                 } catch(Exception e){
1665                         policyEntityList = new LinkedList<>();
1666                 }
1667
1668                 for (PolicyEntity policy: policyEntityList){
1669                         String name = "";
1670                         try {
1671                                 if (!policy.isDeleted()){
1672                                         name = policy.getPolicyName();                          
1673                                         String scope = policy.getScope();
1674
1675                                         scope = scope.replace(".", "//");
1676                                         if (policy.getConfigurationData()!=null){
1677                                                 writePolicySubFile(policy, "Config");
1678                                         }       
1679                                         else if(policy.getActionBodyEntity()!=null){
1680                                                 writePolicySubFile(policy, "Action");
1681                                         }
1682
1683
1684                                         Path fileLocation = Paths.get(webappsPath.toString(), scope);
1685
1686                                         Files.createDirectories(fileLocation);
1687                                         Path newPath = Paths.get(fileLocation.toString(), name);
1688                                         Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData()));
1689                                         XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData);            
1690                                 }
1691                         } catch (Exception e1) {
1692                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while creating Policy File: " + name);
1693                         }               
1694                 }       
1695                 createGroupsFromDatabase();
1696         }
1697
1698         public void deleteAllGroupTables(){
1699                 logger.debug("PolicyDBDao.deleteAllGroupTables() called");
1700                 EntityManager em = emf.createEntityManager();
1701                 em.getTransaction().begin();
1702
1703                 Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll");
1704                 deletePdpEntityEntityTableUpdate.executeUpdate();
1705
1706                 Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll");
1707                 deleteGroupEntityTableUpdate.executeUpdate();
1708
1709                 em.getTransaction().commit();
1710                 em.close();
1711         }
1712
1713         @SuppressWarnings("unchecked")
1714         public void auditGroups(PAPPolicyEngine papEngine2){
1715                 logger.debug("PolicyDBDao.auditGroups() called");
1716
1717                 EntityManager em = emf.createEntityManager();
1718                 em.getTransaction().begin();
1719                 final String AUDIT_STR = "Audit";
1720                 try{
1721
1722                         Set<EcompPDPGroup> groups = papEngine2.getEcompPDPGroups();
1723
1724                         for (EcompPDPGroup grp : groups){
1725                                 try{
1726                                         GroupEntity groupEntity = new GroupEntity();
1727                                         em.persist(groupEntity);
1728                                         groupEntity.setGroupName(grp.getName());
1729                                         groupEntity.setDescription(grp.getDescription());
1730                                         groupEntity.setDefaultGroup(grp.isDefaultGroup());
1731                                         groupEntity.setCreatedBy(AUDIT_STR);
1732                                         groupEntity.setGroupId(createNewPDPGroupId(grp.getId()));
1733                                         groupEntity.setModifiedBy(AUDIT_STR);
1734                                         Set<EcompPDP> pdps =  grp.getEcompPdps();                               
1735
1736                                         for(EcompPDP pdp : pdps){
1737                                                 PdpEntity pdpEntity = new PdpEntity();
1738                                                 em.persist(pdpEntity);
1739                                                 pdpEntity.setGroup(groupEntity);
1740                                                 pdpEntity.setJmxPort(pdp.getJmxPort());
1741                                                 pdpEntity.setPdpId(pdp.getId());
1742                                                 pdpEntity.setPdpName(pdp.getName());
1743                                                 pdpEntity.setModifiedBy(AUDIT_STR);
1744                                                 pdpEntity.setCreatedBy(AUDIT_STR);
1745
1746                                         }
1747
1748                                         Set<PDPPolicy> policies = grp.getPolicies();
1749
1750                                         for(PDPPolicy policy : policies){
1751                                                 try{
1752                                                         String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId());
1753                                                         List<PolicyEntity> policyEntityList;
1754                                                         Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope");
1755                                                         getPolicyEntitiesQuery.setParameter("name", stringArray[0]);
1756                                                         getPolicyEntitiesQuery.setParameter("scope", stringArray[1]);
1757
1758                                                         policyEntityList = getPolicyEntitiesQuery.getResultList();
1759                                                         PolicyEntity policyEntity = null;
1760                                                         if(policyEntityList.size() < 1){
1761                                                                 policyEntity = addPolicyThatOnlyExistsInPdpGroup(policy.getId(),Paths.get(XACMLProperties.getProperty("xacml.pap.pdps"),grp.getId(),policy.getId()),em);
1762                                                         } else {
1763                                                                 policyEntity = policyEntityList.get(0);
1764                                                         }
1765                                                         if(policyEntity != null){
1766                                                                 groupEntity.addPolicyToGroup(policyEntity);
1767                                                         }
1768                                                 }catch(Exception e2){
1769                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Exception auditGroups inner catch");
1770                                                 }
1771                                         }
1772                                 }catch(Exception e1){
1773                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Exception auditGroups middle catch");
1774                                 }
1775                         }
1776                 }catch(Exception e){
1777                         em.getTransaction().rollback();
1778                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception auditGroups outer catch");
1779                         em.close();
1780                         return;
1781                 }
1782
1783                 em.getTransaction().commit();
1784                 em.close();
1785
1786         }
1787
1788         private PolicyEntity addPolicyThatOnlyExistsInPdpGroup(String polId, Path path,EntityManager em){
1789                 String filename = path.getFileName().toString();
1790                 if (filename.contains(".svnignore")){
1791                         return null;
1792                 }
1793
1794                 String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(polId);
1795
1796                 if(scopeAndName == null){
1797                         PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + polId.toString() + " is null!");
1798                         return null;
1799                 }
1800
1801                 PolicyEntity policy = new PolicyEntity();
1802                 em.persist(policy);
1803                 String policyScope = scopeAndName[1];
1804                 String policyName = scopeAndName[0];
1805                 policy.setScope(policyScope);
1806                 policy.setPolicyName(policyName);
1807                 policy.setCreatedBy(AUDIT_USER);
1808                 policy.setModifiedBy(AUDIT_USER);
1809                 policy.setDeleted(true);
1810
1811                 try {
1812                         String policyContent = new String(Files.readAllBytes(path));
1813                         policy.setDescription(getElementFromXMLString("/Description", policyContent));
1814                         policy.setPolicyData(policyContent);
1815                         em.flush();
1816                 } catch (IOException e1) {
1817                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData");
1818                         return null;
1819                 }
1820                 return policy;
1821         }
1822
1823         private String getConfigFile(String filename, PolicyRestAdapter policy){
1824                 if(policy == null){
1825                         return getConfigFile(filename, (String)null);
1826                 }
1827                 return getConfigFile(filename, policy.getConfigType());
1828         }
1829         //copied from ConfigPolicy.java and modified
1830         // Here we are adding the extension for the configurations file based on the
1831         // config type selection for saving.
1832         private String getConfigFile(String filename, String configType) {
1833                 logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile("+filename+", "+configType+") called");
1834                 filename = FilenameUtils.removeExtension(filename);
1835                 String id = configType;
1836
1837                 if (id != null) {
1838                         if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) {
1839                                 filename = filename + ".json";
1840                         }
1841                         if (id.equals(ConfigPolicy.XML_CONFIG)) {
1842                                 filename = filename + ".xml";
1843                         }
1844                         if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) {
1845                                 filename = filename + ".properties";
1846                         }
1847                         if (id.equals(ConfigPolicy.OTHER_CONFIG)) {
1848                                 filename = filename + ".txt";
1849                         }
1850                 }
1851                 return filename;
1852         }
1853
1854         /**
1855          * Constructs the file name of a policy.
1856          * @param policy The name of a policy (ex: mypolicy1)
1857          * @return The file name of the policy (ex: Config_mypolicy1.xml)
1858          * @deprecated
1859          */
1860         @SuppressWarnings("unused")
1861         private String getName(PolicyRestAdapter policy){
1862                 logger.debug("getName(PolicyRestAdapter policy) as getName("+policy+") called");
1863                 String namePrefix = "";
1864                 if(policy.getPolicyType().contains("Config")){
1865                         namePrefix = namePrefix.concat(policy.getPolicyType());
1866                         if(policy.getConfigType().contains("Firewall")){
1867                                 namePrefix = namePrefix.concat("_FW");
1868                         }
1869                 }
1870                 String concats =  namePrefix + "_" +policy.getPolicyName() + ".xml";
1871                 return concats;
1872         }
1873
1874         private String stripPolicyName(String policyFileName){
1875                 String policyName = policyFileName;
1876                 try{
1877                         policyName = policyName.substring(policyName.indexOf('_')+1);
1878                         policyName = removeFileExtension(policyName);
1879                 }catch(Exception e){                                            
1880                         throw new IllegalArgumentException("Could not get name out of policy file name: "+policyName);                                          
1881                 }
1882                 return policyName;
1883         }
1884         
1885         private String[] getNameScopeAndVersionFromPdpPolicy(String fileName){
1886                 String[] splitByDots = fileName.split("\\.");
1887                 if(splitByDots.length < 3){
1888                         //should we throw something
1889                         return null;
1890                 }
1891                 String policyName = splitByDots[splitByDots.length-3];
1892                 String version = splitByDots[splitByDots.length-2];
1893                 //policy names now include version
1894                 String scope = "";
1895                 for(int i=0;i<splitByDots.length-3;i++){
1896                         scope += ".".concat(splitByDots[i]);
1897                 }
1898                 //remove the first dot
1899                 if(scope.length() > 0){
1900                         scope = scope.substring(1);
1901                 }
1902                 String[] returnArray = new String[3];
1903                 returnArray[0] = policyName + "." + version + ".xml";
1904                 returnArray[2] = version;
1905                 returnArray[1] = scope;
1906                 return returnArray;
1907         }
1908
1909         /**
1910          * Constructs the complete repository path based on the properties files
1911          * @return The repository path
1912          */
1913         public static String getGitPath(){
1914                 logger.debug("getGitPath() as getGitPath() called");
1915                 Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin");
1916                 Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY));
1917                 Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString());
1918                 logger.debug("after gitPath: " + gitPath);
1919                 return gitPath.toString();
1920         }
1921
1922         //copied from StdEngine.java
1923         public static String createNewPDPGroupId(String name) {
1924                 String id = name;
1925                 // replace "bad" characters with sequences that will be ok for file names and properties keys.
1926                 id = id.replace(" ", "_sp_");
1927                 id = id.replace("\t", "_tab_");
1928                 id = id.replace("\\", "_bksl_");
1929                 id = id.replace("/", "_sl_");
1930                 id = id.replace(":", "_col_");
1931                 id = id.replace("*", "_ast_");
1932                 id = id.replace("?", "_q_");
1933                 id = id.replace("\"", "_quo_");
1934                 id = id.replace("<", "_lt_");
1935                 id = id.replace(">", "_gt_");
1936                 id = id.replace("|", "_bar_");
1937                 id = id.replace("=", "_eq_");
1938                 id = id.replace(",", "_com_");
1939                 id = id.replace(";", "_scom_");
1940
1941                 return id;
1942         }
1943
1944         /**
1945          * Checks if any of the given strings are empty or null
1946          * @param strings One or more Strings (or nulls) to check if they are null or empty
1947          * @return true if one or more of the given strings are empty or null
1948          */
1949         private static boolean isNullOrEmpty(String... strings){
1950                 for(String s : strings){
1951                         if(!(s instanceof String)){
1952                                 return true;
1953                         }
1954                         if(s.equals("")){
1955                                 return true;
1956                         }
1957                 }
1958                 return false;
1959         }
1960
1961         /**
1962          * Computes the scope, name, and type of a policy based on its file path
1963          * @param path The file path of the policy (including the xml policy file)
1964          * @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.
1965          */
1966         private static String[] getScopeAndNameAndType(String path){
1967                 logger.debug("getScopeAndNameAndType(String path) as getScopeAndNameAndType("+path+") called");
1968                 if(path == null){
1969
1970                 }
1971                 String gitPath  = getGitPath();
1972
1973                 ArrayList<String> gitPathParts = new ArrayList<>();
1974                 Iterator<?> gitPathIterator = Paths.get(gitPath).iterator();
1975                 while(gitPathIterator.hasNext()){
1976                         gitPathParts.add(gitPathIterator.next().toString());
1977                 }
1978                 for(int i=0;i<gitPathParts.size();i++){
1979                         Path testGitPath = Paths.get("");
1980                         for(int j=i;j<gitPathParts.size();j++){
1981                                 testGitPath = Paths.get(testGitPath.toString(),gitPathParts.get(j));
1982                         }
1983                         if(path.contains(testGitPath.toString())){
1984                                 gitPath = testGitPath.toString();
1985                                 break;
1986                         }
1987                 }
1988                 if(gitPath == null){
1989                         logger.debug("gitPath is null.  Returning");
1990                         return null;
1991                 }
1992                 if(gitPath.length() >= path.length()){
1993                         logger.debug("gitPath length(): " + gitPath.length() + ">= path.length(): " + path.length() + ".  Returning null");
1994                         return null;
1995                 }
1996                 String scopeAndName = path.substring(path.indexOf(gitPath)+gitPath.length());
1997
1998                 logger.debug("scopeAndName: " + scopeAndName);
1999                 String policyType = null;
2000                 String[] policyTypes = {"Config_","Action_","Decision_"};
2001                 for(String pType : policyTypes){
2002                         if(scopeAndName.contains(pType)){
2003                                 policyType = pType;
2004                         }
2005                 }
2006                 if(policyType == null){
2007                         return null;
2008                 }
2009                 String scope = scopeAndName.substring(0,scopeAndName.indexOf(policyType));
2010                 String name = scopeAndName.substring(scopeAndName.indexOf(policyType), scopeAndName.length());
2011                 scope = scope.replace('\\', '.');
2012                 scope = scope.replace('/', '.');
2013                 if(scope.length()<1){
2014                         return null;
2015                 }
2016                 if(scope.charAt(0) == '.'){
2017                         if(scope.length() < 2){
2018                                 logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2. " + "| scope.charAt(0)==.");
2019                                 return null;
2020                         }
2021                         scope = scope.substring(1);
2022                 }
2023                 if(scope.charAt(scope.length()-1) == '.'){
2024                         if(scope.length() < 2){
2025                                 logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2" + "| scope.charAt(scope.length()-1)==.");
2026                                 return null;
2027                         }
2028                         scope = scope.substring(0,scope.length()-1);
2029                 }
2030                 if(name.length()<1){
2031                         logger.debug("getScopeAndNameAndType error: name.length()<1");
2032                         return null;
2033                 }
2034                 if(name.charAt(0) == '.'){
2035                         if(name.length() < 2){
2036                                 logger.debug("getScopeAndNameAndType error: " + name.length() + " < 2. " + "| scope.charAt(0)==.");
2037                                 return null;
2038                         }
2039                         name = name.substring(1);
2040                 }
2041                 String[] returnArray = new String[3];
2042                 returnArray[0] = scope;
2043                 returnArray[1] = name;
2044                 //remove the underscore and return it
2045                 returnArray[2] = policyType.substring(0, policyType.length()-1);
2046                 return returnArray;
2047         }
2048
2049
2050         private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction {
2051                 private EntityManager em;
2052                 private final Object emLock = new Object();
2053                 long policyId;
2054                 long groupId;
2055                 long pdpId;
2056                 String newGroupId;
2057                 private boolean operationRun = false;
2058                 private final Thread transactionTimer;
2059
2060                 private PolicyDBDaoTransactionInstance(){
2061                         //call the constructor with arguments
2062                         this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)),
2063                                         Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)));
2064                 }
2065                 //timeout is how long the transaction can sit before rolling back
2066                 //wait time is how long to wait for the transaction to start before throwing an exception
2067                 private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime){
2068                         if(logger.isDebugEnabled()){
2069                                 logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:"
2070                                                 + "\n   transactionTimeout = " + transactionTimeout
2071                                                 + "\n   transactionWaitTime = " + transactionWaitTime + "\n\n");
2072                         }
2073                         this.em = emf.createEntityManager();
2074                         policyId = -1;
2075                         groupId = -1;
2076                         pdpId = -1;
2077                         newGroupId = null;
2078                         synchronized(emLock){
2079                                 try{
2080                                         startTransactionSynced(this.em,transactionWaitTime);
2081                                 } catch(Exception e){
2082                                         throw new PersistenceException("Could not lock transaction within "+transactionWaitTime+" milliseconds");
2083                                 }
2084                         }
2085                         class TransactionTimer implements Runnable {
2086
2087                                 private int sleepTime;
2088                                 public TransactionTimer(int timeout){
2089                                         this.sleepTime = timeout;
2090                                 }
2091                                 @Override
2092                                 public void run() {
2093                                         if(logger.isDebugEnabled()){
2094                                                 Date date= new java.util.Date();
2095                                                 logger.debug("\n\nTransactionTimer.run() - SLEEPING: "
2096                                                                 + "\n   sleepTime (ms) = " + sleepTime 
2097                                                                 + "\n   TimeStamp = " + date.getTime()
2098                                                                 + "\n\n");
2099                                         }
2100                                         try {
2101                                                 Thread.sleep(sleepTime);
2102                                         } catch (InterruptedException e) {
2103                                                 //probably, the transaction was completed, the last thing we want to do is roll back
2104                                                 if(logger.isDebugEnabled()){
2105                                                         Date date= new java.util.Date();
2106                                                         logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: "
2107                                                                         + "\n   TimeStamp = " + date.getTime()
2108                                                                         + "\n\n");
2109                                                 }
2110                                                 return;
2111                                         }
2112                                         if(logger.isDebugEnabled()){
2113                                                 Date date= new java.util.Date();
2114                                                 logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: "
2115                                                                 + "\n   TimeStamp = " + date.getTime()
2116                                                                 + "\n\n");
2117                                         }
2118                                         rollbackTransaction();                                  
2119                                 }
2120
2121                         }
2122
2123                         transactionTimer = new Thread(new TransactionTimer(transactionTimeout),"transactionTimerThread");
2124                         transactionTimer.start();
2125
2126
2127                 }
2128
2129                 private void checkBeforeOperationRun(){
2130                         checkBeforeOperationRun(false);
2131                 }
2132                 private void checkBeforeOperationRun(boolean justCheckOpen){
2133                         if(!isTransactionOpen()){
2134                                 PolicyLogger.error("There is no transaction currently open");
2135                                 throw new IllegalStateException("There is no transaction currently open");
2136                         }
2137                         if(operationRun && !justCheckOpen){
2138                                 PolicyLogger.error("An operation has already been performed and the current transaction should be committed");
2139                                 throw new IllegalStateException("An operation has already been performed and the current transaction should be committed");
2140                         }
2141                         operationRun = true;
2142                 }
2143                 @Override
2144                 public void commitTransaction() {
2145                         synchronized(emLock){
2146                                 logger.debug("commitTransaction() as commitTransaction() called");
2147                                 if(!isTransactionOpen()){
2148                                         logger.warn("There is no open transaction to commit");
2149                                         try{
2150                                                 em.close();
2151                                         } catch(Exception e){
2152                                                 logger.error("Exception Occured"+e);
2153                                         }
2154                                         return;
2155                                 }
2156                                 try{
2157                                         em.getTransaction().commit();
2158                                 } catch(RollbackException e){
2159                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught RollbackException on em.getTransaction().commit()");
2160                                         throw new PersistenceException("The commit failed. Message:\n"+e.getMessage());
2161                                 }
2162                                 em.close();
2163                                 // need to revisit
2164                                 if(policyId >= 0){
2165                                         if(newGroupId != null){
2166                                                 try{
2167                                                         notifyOthers(policyId,POLICY_NOTIFICATION,newGroupId);
2168                                                 } catch(Exception e){
2169                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")");
2170                                                 }
2171                                         } else {
2172                                                 try{
2173                                                         notifyOthers(policyId,POLICY_NOTIFICATION);
2174                                                 } catch(Exception e){
2175                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")");
2176                                                 }
2177                                         }
2178                                 }
2179                                 if(groupId >= 0){
2180                                         //we don't want commit to fail just because this does
2181                                         if(newGroupId != null){
2182                                                 try{
2183                                                         notifyOthers(groupId,GROUP_NOTIFICATION,newGroupId);
2184                                                 } catch(Exception e){
2185                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")");
2186                                                 }
2187                                         } else {
2188                                                 try{
2189                                                         notifyOthers(groupId,GROUP_NOTIFICATION);
2190                                                 } catch(Exception e){
2191                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")");
2192                                                 }
2193                                         }
2194                                 }
2195                                 if(pdpId >= 0){
2196                                         //we don't want commit to fail just because this does
2197                                         try{
2198                                                 notifyOthers(pdpId,PDP_NOTIFICATION);
2199                                         } catch(Exception e){
2200                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")");
2201                                         }
2202                                 }
2203                         }
2204                         if(transactionTimer instanceof Thread){
2205                                 transactionTimer.interrupt();
2206                         }
2207                 }
2208
2209                 @Override
2210                 public void rollbackTransaction() {
2211                         logger.debug("rollbackTransaction() as rollbackTransaction() called");
2212                         synchronized(emLock){
2213                                 if(isTransactionOpen()){        
2214
2215                                         try{
2216                                                 em.getTransaction().rollback();                                 
2217                                         } catch(Exception e){
2218                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not rollback transaction");
2219                                         }
2220                                         try{
2221                                                 em.close();
2222                                         }catch(Exception e){
2223                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not close EntityManager");
2224                                         }
2225
2226                                 } else {
2227                                         try{
2228                                                 em.close();
2229                                         }catch(Exception e){
2230                                                 logger.warn("Could not close already closed transaction");
2231                                         }
2232                                 }
2233
2234                         }
2235                         if(transactionTimer instanceof Thread){
2236                                 transactionTimer.interrupt();
2237                         }
2238
2239
2240                 }
2241
2242                 private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) {
2243                         logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) as createPolicy("+policy+", "+username+", "+policyScope+", "+policyName+", "+policyDataString+") called");
2244                         synchronized(emLock){
2245                                 checkBeforeOperationRun();
2246                                 String configName = policyName;
2247                                 if(policyName.contains("Config_")){
2248                                         policyName = policyName.replace(".Config_", ":Config_");
2249                                 }else if(policyName.contains("Action_")){
2250                                         policyName = policyName.replace(".Action_", ":Action_");
2251                                 }else if(policyName.contains("Decision_")){
2252                                         policyName = policyName.replace(".Decision_", ":Decision_");
2253                                 }
2254                                 policyName = policyName.split(":")[1];
2255                                 Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName");                     
2256                                 createPolicyQuery.setParameter("scope", policyScope);
2257                                 createPolicyQuery.setParameter("policyName", policyName);
2258                                 List<?> createPolicyQueryList = createPolicyQuery.getResultList();
2259                                 PolicyEntity newPolicyEntity;
2260                                 boolean update;
2261                                 if(createPolicyQueryList.size() < 1){
2262                                         newPolicyEntity = new PolicyEntity();
2263                                         update = false;
2264                                 } else if(createPolicyQueryList.size() > 1){
2265                                         PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
2266                                         throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
2267                                 } else {
2268                                         newPolicyEntity = (PolicyEntity)createPolicyQueryList.get(0);
2269                                         update = true;
2270                                 }                       
2271
2272                                 ActionBodyEntity newActionBodyEntity = null;
2273                                 if(policy.getPolicyType().equals("Action")){
2274                                         boolean abupdate = false;
2275                                         if(newPolicyEntity.getActionBodyEntity() == null){
2276                                                 newActionBodyEntity = new ActionBodyEntity();
2277                                         }else{
2278                                                 newActionBodyEntity = em.find(ActionBodyEntity.class, newPolicyEntity.getActionBodyEntity().getActionBodyId());
2279                                                 abupdate = true;
2280                                         }
2281
2282                                         if(newActionBodyEntity != null){
2283                                                 if(!abupdate){
2284                                                         em.persist(newActionBodyEntity);
2285                                                 }
2286                                                 //build the file path
2287                                                 //trim the .xml off the end
2288                                                 String policyNameClean = FilenameUtils.removeExtension(configName);
2289                                                 String actionBodyName =  policyNameClean + ".json";
2290                                                 Path actionBodyPath = Paths.get(Webapps.getActionHome(), actionBodyName);
2291                                                 if(logger.isDebugEnabled()){
2292                                                         logger.debug("\nPolicyDBDao.createPolicy"
2293                                                                         + "\n   actionBodyPath = " + actionBodyPath);
2294                                                 }
2295                                                 //get the action body
2296                                                 String actionBodyString = null;
2297                                                 String actionBodyPathStr = null;
2298                                                 InputStream fileContentStream = null;
2299
2300                                                 if (Files.exists(actionBodyPath)) {
2301                                                         try {
2302                                                                 actionBodyPathStr = (actionBodyPath != null ? actionBodyPath.toString() : null);
2303                                                                 fileContentStream = new FileInputStream(actionBodyPathStr);
2304                                                                 actionBodyString = IOUtils.toString(fileContentStream);
2305                                                                 if(logger.isDebugEnabled()){
2306                                                                         logger.debug("\nPolicyDBDao.createPolicy"
2307                                                                                         + "\n   actionBodyPathStr = " + actionBodyPathStr
2308                                                                                         + "\n   actionBodyString = " + actionBodyString);
2309                                                                 }
2310                                                         } catch (FileNotFoundException e) {
2311                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")");
2312                                                                 throw new IllegalArgumentException("The actionBodyPathStr file path " + actionBodyPathStr + " does not exist" 
2313                                                                                 + "\nEXCEPTION: " + e);
2314                                                         } catch(IOException e2){
2315                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")");
2316                                                                 throw new IllegalArgumentException("The actionBodyPath file path cannot be read" + fileContentStream 
2317                                                                                 + "\nEXCEPTION: " + e2);
2318                                                         } finally {
2319                                                                 IOUtils.closeQuietly(fileContentStream);
2320                                                         }
2321
2322                                                         if(actionBodyString == null){
2323                                                                 throw new IllegalArgumentException("The file path (" + actionBodyPathStr + ") cannot be read");
2324                                                         }
2325                                                 } else {
2326                                                         actionBodyString = "{}";
2327                                                 }
2328
2329                                                 newActionBodyEntity.setActionBody(actionBodyString);
2330                                                 newActionBodyEntity.setActionBodyName(actionBodyName);
2331                                                 newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()");
2332                                                 newActionBodyEntity.setDeleted(false);
2333                                                 if(!abupdate){
2334                                                         newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()");
2335                                                 }
2336                                                 if(logger.isDebugEnabled()){
2337                                                         logger.debug("\nPolicyDBDao.createPolicy"
2338                                                                         + "\n   newActionBodyEntity.getActionBody() = " + newActionBodyEntity.getActionBody()
2339                                                                         + "\n   newActionBodyEntity.getActionBodyName() = " + newActionBodyEntity.getActionBodyName()
2340                                                                         + "\n   newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy()
2341                                                                         + "\n   newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy()
2342                                                                         + "\n   newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted()
2343                                                                         + "\n   FLUSHING to DB");
2344                                                 }
2345                                                 //push the actionBodyEntity to the DB
2346                                                 em.flush();
2347                                         }else{
2348                                                 //newActionBodyEntity == null
2349                                                 //We have a actionBody in the policy but we found no actionBody in the DB
2350                                                 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an "
2351                                                                 + "actionBody, but it could not be found in the DB for update."
2352                                                                 + "\n  policyScope = " + policyScope
2353                                                                 + "\n  policyName = " + policyName + "\n\n";
2354                                                 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it could not be found in the DB for update: policyName = " + policyName);
2355                                                 throw new IllegalArgumentException(msg);
2356                                         }
2357                                 }
2358
2359                                 ConfigurationDataEntity newConfigurationDataEntity;
2360                                 if(policy.getPolicyType().equals("Config")){
2361                                         boolean configUpdate;
2362                                         if(newPolicyEntity.getConfigurationData() == null){
2363                                                 newConfigurationDataEntity = new ConfigurationDataEntity();
2364                                                 configUpdate = false;
2365                                         } else {
2366                                                 newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, newPolicyEntity.getConfigurationData().getConfigurationDataId());
2367                                                 configUpdate = true;
2368                                         }
2369
2370                                         if(newConfigurationDataEntity != null){
2371                                                 if(!configUpdate){
2372                                                         em.persist(newConfigurationDataEntity);
2373                                                 }
2374                                                 if(!stringEquals(newConfigurationDataEntity.getConfigurationName(),getConfigFile(configName,policy))){
2375                                                         newConfigurationDataEntity.setConfigurationName(getConfigFile(configName,policy));
2376                                                 }
2377                                                 if(newConfigurationDataEntity.getConfigType() == null || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())){
2378                                                         newConfigurationDataEntity.setConfigType(policy.getConfigType());
2379                                                 }
2380                                                 if(!configUpdate){
2381                                                         newConfigurationDataEntity.setCreatedBy(username);
2382                                                 }
2383                                                 if(newConfigurationDataEntity.getModifiedBy() == null || !newConfigurationDataEntity.getModifiedBy().equals(username)){
2384                                                         newConfigurationDataEntity.setModifiedBy(username);
2385                                                 }                                       
2386                                                 if(newConfigurationDataEntity.getDescription() == null || !newConfigurationDataEntity.getDescription().equals("")){
2387                                                         newConfigurationDataEntity.setDescription("");
2388                                                 }
2389                                                 if(newConfigurationDataEntity.getConfigBody() == null || newConfigurationDataEntity.getConfigBody().isEmpty() ||
2390                                                                 (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))){
2391                                                         //hopefully one of these won't be null
2392                                                         if(policy.getConfigBodyData() == null || policy.getConfigBodyData().isEmpty()){
2393                                                                 newConfigurationDataEntity.setConfigBody(policy.getJsonBody());
2394                                                         }else{
2395                                                                 newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData());
2396                                                         }
2397                                                 }
2398                                                 if(newConfigurationDataEntity.isDeleted() == true){
2399                                                         newConfigurationDataEntity.setDeleted(false);
2400                                                 }
2401
2402                                                 em.flush();
2403                                         }else{
2404                                                 //We have a configurationData body in the policy but we found no configurationData body in the DB
2405                                                 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a "
2406                                                                 + "configurationData body, but it could not be found in the DB for update."
2407                                                                 + "\n  policyScope = " + policyScope
2408                                                                 + "\n  policyName = " + policyName + "\n\n";
2409                                                 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, but it could not be found in the DB for update: policyName = " + policyName);
2410                                                 throw new IllegalArgumentException(msg);
2411                                         }
2412
2413                                 } else {
2414                                         newConfigurationDataEntity = null;
2415                                 }
2416                                 if(!update){
2417                                         em.persist(newPolicyEntity);
2418                                 }
2419
2420                                 policyId = newPolicyEntity.getPolicyId();
2421
2422                                 if(!stringEquals(newPolicyEntity.getPolicyName(),policyName)){
2423                                         newPolicyEntity.setPolicyName(policyName);
2424                                 }
2425                                 if(!stringEquals(newPolicyEntity.getCreatedBy(),username)){
2426                                         newPolicyEntity.setCreatedBy(username);
2427                                 }
2428                                 if(!stringEquals(newPolicyEntity.getDescription(),policy.getPolicyDescription())){
2429                                         newPolicyEntity.setDescription(policy.getPolicyDescription());
2430                                 }
2431                                 if(!stringEquals(newPolicyEntity.getModifiedBy(),username)){
2432                                         newPolicyEntity.setModifiedBy(username);
2433                                 }
2434                                 if(!stringEquals(newPolicyEntity.getPolicyData(),policyDataString)){
2435                                         newPolicyEntity.setPolicyData(policyDataString);
2436                                 }
2437                                 if(!stringEquals(newPolicyEntity.getScope(),policyScope)){
2438                                         newPolicyEntity.setScope(policyScope);
2439                                 }
2440                                 if(newPolicyEntity.isDeleted() == true){
2441                                         newPolicyEntity.setDeleted(false);
2442                                 }
2443                                 newPolicyEntity.setConfigurationData(newConfigurationDataEntity);
2444                                 newPolicyEntity.setActionBodyEntity(newActionBodyEntity);
2445
2446
2447                                 em.flush();
2448                                 this.policyId = newPolicyEntity.getPolicyId();
2449                         }
2450
2451                         return;
2452                 }
2453
2454                 @SuppressWarnings("unused")
2455                 public PolicyEntity getPolicy(int policyID){
2456                         return getPolicy(policyID,null,null);
2457                 }
2458                 public PolicyEntity getPolicy(String policyName,String scope){
2459                         return getPolicy(-1,policyName,scope);
2460                 }
2461                 private PolicyEntity getPolicy(int policyID, String policyName,String scope){
2462                         logger.debug("getPolicy(int policyId, String policyName) as getPolicy("+policyID+","+policyName+") called");
2463                         if(policyID < 0 && isNullOrEmpty(policyName,scope)){
2464                                 throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank");
2465                         }
2466
2467                         synchronized(emLock){
2468                                 checkBeforeOperationRun(true);
2469                                 //check if group exists
2470                                 String policyId;
2471                                 Query policyQuery;
2472                                 if(!isNullOrEmpty(policyName,scope)){
2473                                         policyId = policyName;
2474                                         policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope");
2475                                         policyQuery.setParameter("name", policyId);
2476                                         policyQuery.setParameter("scope", scope);
2477                                 } else{
2478                                         policyId = String.valueOf(policyID);
2479                                         policyQuery = em.createNamedQuery("PolicyEntity.FindById");
2480                                         policyQuery.setParameter("id", policyId);
2481                                 }
2482                                 List<?> policyQueryList;
2483                                 try{
2484                                         policyQueryList = policyQuery.getResultList();
2485                                 }catch(Exception e){
2486                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get policy with policyQuery.getResultList()");
2487                                         throw new PersistenceException("Query failed trying to get policy "+policyId);
2488                                 }
2489                                 if(policyQueryList.size() < 1){
2490                                         PolicyLogger.error("Policy does not exist with id "+policyId);
2491                                         throw new PersistenceException("Group policy is being added to does not exist with id "+policyId);
2492                                 } else if(policyQueryList.size() > 1){
2493                                         PolicyLogger.error("Somehow, more than one policy with the id "+policyId+" were found in the database");
2494                                         throw new PersistenceException("Somehow, more than one policy with the id "+policyId+" were found in the database");
2495                                 }
2496                                 return (PolicyEntity)policyQueryList.get(0);
2497                         }
2498                 }
2499
2500                 @Override
2501                 public void renamePolicy(String oldPath, String newPath,String username){
2502                         String[] oldPolicy = getScopeAndNameAndType(oldPath);
2503                         String[] newPolicy = getScopeAndNameAndType(newPath);
2504                         if(oldPolicy == null || newPolicy == null){
2505                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
2506                                                 +oldPath+", "+newPath);
2507                                 throw new IllegalArgumentException("Could not parse one or more of the path names");
2508                         }
2509                         synchronized (emLock) {
2510                                 checkBeforeOperationRun();
2511
2512                                 PolicyEntity existingPolicy;
2513                                 boolean existingPolicyDeleted = false;
2514                                 List<?> groups = null;
2515                                 try{
2516                                         existingPolicy = getPolicy(newPolicy[1],newPolicy[0]);
2517                                 } catch(Exception e){
2518                                         existingPolicy = null;
2519                                 }
2520                                 if(existingPolicy != null && !existingPolicy.isDeleted()){
2521                                         logger.error("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
2522                                         throw new IllegalArgumentException("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
2523                                 } else if(existingPolicy != null && existingPolicy.isDeleted()){
2524                                         try{
2525                                                 Query getGroups = em.createQuery("SELECT g FROM GroupEntity g JOIN g.policies p WHERE p.policyId=:pid");
2526
2527                                                 getGroups.setParameter("pid", existingPolicy.getPolicyId());
2528                                                 groups = getGroups.getResultList();
2529                                         }catch(Exception e){
2530                                                 groups = new LinkedList<>();
2531                                         }
2532                                         for(Object o : groups){
2533                                                 GroupEntity group = (GroupEntity)o;
2534                                                 group.removePolicyFromGroup(existingPolicy);
2535                                         }
2536                                         try{
2537                                                 em.flush();
2538                                         }catch(Exception e){
2539                                                 logger.error("Error while removing the policy from groups: "+existingPolicy.getPolicyName());
2540                                         }
2541                                         try{
2542                                                 em.remove(existingPolicy);
2543                                                 em.flush();
2544                                         }catch(Exception e){
2545                                                 logger.error("Could not remove the existing deleted policy: "+existingPolicy.getPolicyName());
2546                                         }
2547                                         existingPolicyDeleted = true;
2548                                         //create the new policy
2549                                         //for each of the groups, add the new policy
2550                                 }
2551
2552                                 PolicyEntity policyToRename;
2553                                 try{
2554                                         policyToRename = getPolicy(oldPolicy[1],oldPolicy[0]);
2555                                 } catch(Exception e){
2556                                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to rename: "
2557                                                         +oldPolicy[1]);
2558                                         throw new PersistenceException("Could not get policy record to rename");
2559                                 }
2560                                 String policyDataString = null;
2561                                 InputStream fileContentStream = null;
2562                                 String policyFilePath = Paths.get(oldPath).toAbsolutePath().toString();
2563                                 //I want to try the old path first, then if it doesn't work, try the new path
2564                                 for(int i=0;i<2;i++){
2565                                         try {
2566                                                 fileContentStream = new FileInputStream(policyFilePath);
2567                                                 policyDataString = IOUtils.toString(fileContentStream);
2568                                         } catch (FileNotFoundException e) {
2569                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+policyFilePath+")");
2570                                                 //if we can't find the oldPath, we'll try the new path
2571                                                 if(i == 0){
2572                                                         policyFilePath = Paths.get(newPath).toAbsolutePath().toString();
2573                                                         continue;
2574                                                 }
2575                                                 throw new IllegalArgumentException("The file path does not exist");
2576                                         } catch(IOException e2){
2577                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")");
2578                                                 throw new IllegalArgumentException("The file path cannot be read");
2579                                         } finally {
2580                                                 IOUtils.closeQuietly(fileContentStream);
2581                                         }
2582                                         if(policyDataString == null){
2583                                                 throw new IllegalArgumentException("The file path cannot be read");
2584                                         }
2585                                         //escape the loop
2586                                         i=2;
2587                                 }
2588                                 policyToRename.setPolicyName(newPolicy[1]);
2589                                 policyToRename.setPolicyData(policyDataString);
2590                                 policyToRename.setScope(newPolicy[0]);
2591                                 policyToRename.setModifiedBy(username);
2592                                 if(policyToRename.getConfigurationData() != null){
2593                                         String configType = policyToRename.getConfigurationData().getConfigType();
2594                                         policyToRename.getConfigurationData().setConfigurationName(getConfigFile(newPolicy[1], configType));
2595                                         policyToRename.getConfigurationData().setModifiedBy(username);
2596                                 }
2597                                 if(policyToRename.getActionBodyEntity() != null){
2598                                         String newActionName = newPolicy[0]+"."+removeFileExtension(newPolicy[1])+".json";
2599                                         policyToRename.getActionBodyEntity().setActionBodyName(newActionName);
2600                                         policyToRename.getActionBodyEntity().setModifiedBy(username);
2601                                 }
2602                                 if(existingPolicyDeleted){
2603                                         for(Object o : groups){
2604
2605                                                 GroupEntity group = (GroupEntity)o;
2606                                                 group.addPolicyToGroup(policyToRename);
2607                                         }
2608                                 }
2609                                 em.flush();
2610                                 this.policyId = policyToRename.getPolicyId();
2611                                 this.newGroupId = oldPath;
2612                         }
2613                 }
2614
2615                 @Override
2616                 public GroupEntity getGroup(long groupKey){
2617                         logger.debug("getGroup(int groupKey) as getGroup("+groupKey+") called");
2618                         if(groupKey < 0){
2619                                 throw new IllegalArgumentException("groupKey must be at least 0");
2620                         }
2621                         synchronized(emLock){
2622                                 checkBeforeOperationRun(true);
2623                                 //check if group exists
2624                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey");
2625                                 groupQuery.setParameter("groupKey", groupKey);                  
2626                                 List<?> groupQueryList;
2627                                 try{
2628                                         groupQueryList = groupQuery.getResultList();
2629                                 }catch(Exception e){
2630                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
2631                                         throw new PersistenceException("Query failed trying to get group "+groupKey);
2632                                 }
2633                                 if(groupQueryList.size() < 1){
2634                                         PolicyLogger.error("Group does not exist with groupKey "+groupKey);
2635                                         throw new PersistenceException("Group does not exist with groupKey "+groupKey);
2636                                 } else if(groupQueryList.size() > 1){
2637                                         PolicyLogger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
2638                                         throw new PersistenceException("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
2639                                 }
2640                                 return (GroupEntity)groupQueryList.get(0);
2641                         }
2642                 }
2643
2644                 @Override
2645                 public GroupEntity getGroup(String groupId){
2646                         logger.debug("getGroup(String groupId) as getGroup("+groupId+") called");
2647                         if(isNullOrEmpty(groupId)){
2648                                 throw new IllegalArgumentException("groupId must not be null or empty");
2649                         }
2650                         synchronized(emLock){
2651                                 checkBeforeOperationRun(true);
2652                                 //check if group exists
2653                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId");
2654                                 groupQuery.setParameter("groupId", groupId);                    
2655                                 List<?> groupQueryList;
2656                                 try{
2657                                         groupQueryList = groupQuery.getResultList();
2658                                 }catch(Exception e){
2659                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
2660                                         throw new PersistenceException("Query failed trying to get group "+groupId);
2661                                 }
2662                                 if(groupQueryList.size() < 1){
2663                                         PolicyLogger.error("Group does not exist with id "+groupId);
2664                                         throw new PersistenceException("Group does not exist with id "+groupId);
2665                                 } else if(groupQueryList.size() > 1){
2666                                         PolicyLogger.error("Somehow, more than one group with the id "+groupId+" were found in the database");
2667                                         throw new PersistenceException("Somehow, more than one group with the id "+groupId+" were found in the database");
2668                                 }
2669                                 return (GroupEntity)groupQueryList.get(0);
2670                         }
2671                 }
2672                 @Override
2673                 public List<?> getPdpsInGroup(long groupKey){
2674                         logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup("+groupKey+") called");
2675                         if(groupKey < 0){
2676                                 throw new IllegalArgumentException("groupId must not be < 0");
2677                         }                       
2678                         synchronized(emLock){
2679                                 checkBeforeOperationRun(true);
2680                                 Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group");
2681                                 pdpsQuery.setParameter("group", getGroup(groupKey));
2682                                 return pdpsQuery.getResultList();
2683                         }
2684                 }
2685                 @Override
2686                 public PdpEntity getPdp(long pdpKey){
2687                         logger.debug("getPdp(int pdpKey) as getPdp("+pdpKey+") called");
2688                         if(pdpKey < 0){
2689                                 throw new IllegalArgumentException("pdpKey must be at least 0");
2690                         }
2691                         synchronized(emLock){
2692                                 checkBeforeOperationRun(true);
2693                                 //check if group exists
2694                                 Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey");
2695                                 pdpQuery.setParameter("pdpKey", pdpKey);                        
2696                                 List<?> pdpQueryList;
2697                                 try{
2698                                         pdpQueryList = pdpQuery.getResultList();
2699                                 }catch(Exception e){
2700                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp with pdpQuery.getResultList()");
2701                                         throw new PersistenceException("Query failed trying to get pdp "+pdpKey);
2702                                 }
2703                                 if(pdpQueryList.size() < 1){
2704                                         PolicyLogger.error("Pdp does not exist with pdpKey "+pdpKey);
2705                                         throw new PersistenceException("Pdp does not exist with pdpKey "+pdpKey);
2706                                 } else if(pdpQueryList.size() > 1){
2707                                         PolicyLogger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
2708                                         throw new PersistenceException("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
2709                                 }
2710                                 return (PdpEntity)pdpQueryList.get(0);
2711                         }
2712                 }
2713                 
2714                 public void deletePolicy(String policyToDeletes){
2715                         synchronized(emLock){
2716                                 checkBeforeOperationRun();
2717                                 logger.debug("deletePolicy(String policyToDeletes) as deletePolicy("+policyToDeletes+") called");
2718                                 String[] scopeNameAndType = getScopeAndNameAndType(policyToDeletes);
2719                                 if(scopeNameAndType == null){
2720                                         throw new IllegalArgumentException("Could not parse file path");
2721                                 }
2722                                 String realScope = scopeNameAndType[0];
2723                                 String realName = scopeNameAndType[1];
2724                                 Query deletePolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName AND p.deleted=:deleted");                      
2725                                 deletePolicyQuery.setParameter("scope",realScope);
2726                                 deletePolicyQuery.setParameter("policyName", realName);
2727                                 deletePolicyQuery.setParameter("deleted", false);
2728                                 List<?> deletePolicyQueryList = deletePolicyQuery.getResultList();
2729                                 if(deletePolicyQueryList.size() < 1){
2730                                         logger.warn("The policy being deleted could not be found.");
2731                                         return;
2732                                 } else if(deletePolicyQueryList.size() > 1){
2733                                         PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
2734                                         throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
2735                                 } else {
2736                                         PolicyEntity policyToDelete = (PolicyEntity)deletePolicyQueryList.get(0);
2737                                         policyToDelete.setDeleted(true);
2738                                         if(policyToDelete.getConfigurationData() != null){
2739                                                 ConfigurationDataEntity cde = em.find(ConfigurationDataEntity.class,policyToDelete.getConfigurationData().getConfigurationDataId());                                    
2740                                                 if(cde != null){
2741                                                         cde.setDeleted(true);
2742                                                 }
2743                                         }
2744                                         if(policyToDelete.getActionBodyEntity() != null){
2745                                                 ActionBodyEntity abe = em.find(ActionBodyEntity.class,policyToDelete.getActionBodyEntity().getActionBodyId());                                  
2746                                                 if(abe != null){
2747                                                         abe.setDeleted(true);
2748                                                 }
2749                                         }
2750
2751                                         em.flush();
2752                                         this.policyId = policyToDelete.getPolicyId();
2753
2754                                 }
2755                         }
2756
2757                 }
2758
2759
2760                 @Override
2761                 public boolean isTransactionOpen() {
2762                         logger.debug("isTransactionOpen() as isTransactionOpen() called");
2763                         synchronized(emLock){
2764                                 return em.isOpen() && em.getTransaction().isActive();   
2765                         }
2766                 }
2767
2768
2769                 @Override
2770                 public void clonePolicy(String oldPolicyPath, String newPolicyPath, String username){
2771                         String[] oldPolicyData = getScopeAndNameAndType(oldPolicyPath);
2772                         String[] newPolicyData = getScopeAndNameAndType(newPolicyPath);
2773                         if(oldPolicyData == null || newPolicyData == null){
2774                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
2775                                                 +oldPolicyPath+", "+newPolicyPath);
2776                                 throw new IllegalArgumentException("Could not parse the oldPolicyPath or newPolicyPath");
2777                         }
2778                         PolicyEntity oldPolicy;
2779                         try{
2780                                 oldPolicy = getPolicy(oldPolicyData[1],oldPolicyData[0]);
2781                         }catch(Exception e){
2782                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to clone: "
2783                                                 +oldPolicyData[1]);
2784                                 throw new PersistenceException("Could not get policy record to clone");
2785                         }
2786                         ConfigurationDataEntity clonedConfig = null;
2787                         if(oldPolicy.getConfigurationData() != null){
2788                                 clonedConfig = new ConfigurationDataEntity();
2789                                 em.persist(clonedConfig);
2790                                 clonedConfig.setConfigBody(oldPolicy.getConfigurationData().getConfigBody());
2791                                 clonedConfig.setConfigType(oldPolicy.getConfigurationData().getConfigType());
2792                                 clonedConfig.setCreatedBy(username);
2793                                 clonedConfig.setConfigurationName(getConfigFile(newPolicyData[1], oldPolicy.getConfigurationData().getConfigType()));
2794                                 clonedConfig.setDescription(oldPolicy.getConfigurationData().getDescription());
2795                                 clonedConfig.setModifiedBy(username);
2796                                 em.flush();
2797                         }
2798                         ActionBodyEntity clonedAction = null;
2799                         if(oldPolicy.getActionBodyEntity() != null){
2800                                 clonedAction = new ActionBodyEntity();
2801                                 em.persist(clonedAction);
2802                                 clonedAction.setActionBody(oldPolicy.getActionBodyEntity().getActionBody());
2803                                 clonedAction.setActionBodyName(newPolicyData[0]+"."+newPolicyData[1]+".json");
2804                                 clonedAction.setCreatedBy(username);
2805                                 clonedAction.setModifiedBy(username);
2806                                 em.flush();
2807                         }                       
2808
2809
2810                 }
2811
2812                 @Override
2813                 public void createPolicy(String filePath, String username) {
2814                         logger.debug("createPolicy(String filePath, String username) as createPolicy("+filePath+","+username+") called");
2815                         //get just the scope and file name
2816                         //its actually scope, name, and type now
2817                         String[] scopeAndName = getScopeAndNameAndType(filePath);
2818                         if(scopeAndName == null){
2819                                 throw new IllegalArgumentException("The file path could not be parsed");
2820                         }
2821                         PolicyRestAdapter policy = new PolicyRestAdapter();
2822
2823                         policy.setPolicyType(scopeAndName[2]);
2824                         policy.setPolicyDescription("");
2825
2826                         String policyName = scopeAndName[1];
2827                         try{
2828                                 policyName = stripPolicyName(policyName);
2829                         }catch(IllegalArgumentException e){
2830                                 if(scopeAndName[2].equals("Config")){
2831                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception calling stripPolicyName with policy name: "+policyName);
2832                                         throw new IllegalArgumentException(e.getMessage(),e);
2833                                 } else {
2834                                         logger.warn(e.getMessage());
2835                                 }
2836                         }
2837                         policy.setPolicyName(policyName);
2838                         String policyDataString = null;
2839                         InputStream fileContentStream = null;
2840                         try {
2841                                 fileContentStream = new FileInputStream(filePath);
2842                                 policyDataString = IOUtils.toString(fileContentStream);
2843                         } catch (FileNotFoundException e) {
2844                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+filePath+")");
2845                                 throw new IllegalArgumentException("The file path does not exist");
2846                         } catch(IOException e2){
2847                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")");
2848                                 throw new IllegalArgumentException("The file path cannot be read");
2849                         } finally {
2850                                 IOUtils.closeQuietly(fileContentStream);
2851                         }
2852                         if(policyDataString == null){
2853                                 throw new IllegalArgumentException("The file path cannot be read");
2854                         }
2855                         try{
2856                                 String policyDescription = getElementFromXMLString("/Description", policyDataString);
2857                                 if(policyDescription != null){
2858                                         policy.setPolicyDescription(policyDescription);
2859                                 }
2860                         } catch(Exception e){
2861                                 logger.warn("Could not get description from the policy file");
2862                         }
2863                         if(scopeAndName[2].equals("Config")){
2864                                 //this method is not used for config, since there is no way to get config info (could be modified to)
2865                                 String configPath;
2866                                 try{
2867                                         configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
2868                                         if(configPath == null){
2869                                                 throw new NullPointerException("configPath is null");
2870                                         }
2871                                 } catch(Exception e){
2872                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get config file path from policy file");
2873                                         throw new IllegalArgumentException("Could not get config file path from policy file");
2874                                 }
2875                                 configPath = processConfigPath(configPath);
2876                                 logger.debug("The location of our config file is: "+configPath);
2877                                 policy.setConfigType(getPolicySubType(configPath));
2878                                 logger.debug("Config type is: "+policy.getConfigType());
2879
2880                                 String configDataString = readConfigFile(configPath);
2881                                 policy.setConfigBodyData(configDataString);
2882                         }
2883                         createPolicy(policy,username,scopeAndName[0],scopeAndName[1],policyDataString);                 
2884                 }
2885                 
2886                 private String processConfigPath(String configPath){
2887                         String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS);
2888                         if(webappsPath == null){
2889                                 logger.error("Webapps property does not exist");
2890                                 throw new IllegalArgumentException("Webapps property does not exist");
2891                         }
2892                         configPath = configPath.replace("$URL", webappsPath);
2893                         //make sure the correct slashes are in
2894                         try{
2895                                 configPath = Paths.get(configPath).toString();
2896                         } catch(InvalidPathException e){
2897                                 logger.error("Invalid config path: "+configPath);
2898                                 throw new IllegalArgumentException("Invalid config path: "+configPath);
2899                         }
2900                         return configPath;
2901                 }
2902                 private String readConfigFile(String configPath){
2903                         String configDataString = null;
2904                         InputStream configContentStream = null;
2905                         try {
2906                                 configContentStream = new FileInputStream(configPath);
2907                                 configDataString = IOUtils.toString(configContentStream);
2908                         } catch (FileNotFoundException e) {
2909                                 logger.error("Caught FileNotFoundException on new FileInputStream("+configPath+")",e);
2910                                 throw new IllegalArgumentException("The config file path does not exist");
2911                         } catch(IOException e2){
2912                                 logger.error("Caught IOException on newIOUtils.toString("+configContentStream+")",e2);
2913                                 throw new IllegalArgumentException("The config file path cannot be read");
2914                         } finally {
2915                                 IOUtils.closeQuietly(configContentStream);
2916                         }
2917                         if(configDataString == null){
2918                                 throw new IllegalArgumentException("The config file path cannot be read");
2919                         }
2920                         return configDataString;
2921                 }
2922
2923                 @Override
2924                 public void createPolicy(Policy policy, String username){
2925                         logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy("+policy+","+username+") called");
2926                         String policyScope = policy.policyAdapter.getDomainDir().replace(File.separator, ".");
2927                         //Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
2928                         //and this transaction is intercepted up stream.
2929                         InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType)policy.getCorrectPolicyDataObject());
2930                         String policyDataString;
2931                         try {
2932                                 policyDataString = IOUtils.toString(policyXmlStream);
2933                         } catch (IOException e) {
2934                                 policyDataString = "could not read";
2935                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught IOException on IOUtils.toString("+policyXmlStream+")");
2936                                 throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter.");
2937                         }
2938                         IOUtils.closeQuietly(policyXmlStream);
2939                         String configPath = "";
2940                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
2941                                 configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
2942                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
2943                                 configPath = evaluateXPath("/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " +policy.policyAdapter.getActionAttribute()+ ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", policyDataString);
2944                         }
2945
2946                         String prefix = null;
2947                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
2948
2949                                 prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName()));
2950                                 if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){
2951                                         String configData = "";
2952                                         try{
2953                                                 String newConfigPath = configPath;
2954                                                 try{
2955                                                         newConfigPath = processConfigPath(newConfigPath);                                                       
2956                                                 }catch(Exception e2){
2957                                                         logger.error("Could not process config path: "+newConfigPath,e2);
2958                                                 }
2959                                                 configData = readConfigFile(newConfigPath);
2960                                         }catch(Exception e){
2961                                                 logger.error("Could not read config body data for "+configPath,e);
2962                                         }
2963                                         policy.policyAdapter.setConfigBodyData(configData);
2964                                 }
2965                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
2966                                 prefix = "Action_";
2967                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Decision")) {
2968                                 prefix = "Decision_";
2969                         }
2970
2971                         if(!(policy.policyAdapter.getData() instanceof PolicyType)){
2972                                 PolicyLogger.error("The data field is not an instance of PolicyType");
2973                                 throw new IllegalArgumentException("The data field is not an instance of PolicyType");
2974                         }
2975                         String finalName = policyScope + "." + prefix+policy.policyAdapter.getPolicyName()+"."+((PolicyType)policy.policyAdapter.getData()).getVersion()+".xml";
2976                         if(policy.policyAdapter.getConfigType() == null || policy.policyAdapter.getConfigType().equals("")){
2977                                 //get the config file extension
2978                                 String ext = "";
2979                                 if (configPath != null) {
2980                                         if (!configPath.equalsIgnoreCase("")) {
2981                                                 ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());;
2982                                         }
2983                                 }
2984
2985                                 if(ext.contains("txt")){
2986                                         policy.policyAdapter.setConfigType(OTHER_CONFIG);
2987                                 } else if(ext.contains("json")){
2988                                         policy.policyAdapter.setConfigType(JSON_CONFIG);
2989                                 } else if(ext.contains("xml")){
2990                                         policy.policyAdapter.setConfigType(XML_CONFIG);
2991                                 } else if(ext.contains("properties")){
2992                                         policy.policyAdapter.setConfigType(PROPERTIES_CONFIG);
2993                                 } else {
2994                                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")){
2995                                                 policy.policyAdapter.setConfigType(JSON_CONFIG);
2996                                         }
2997                                 }
2998                         }
2999                         createPolicy(policy.policyAdapter, username, policyScope,finalName,policyDataString);
3000
3001                 }
3002
3003                 @Override
3004                 public void close(){
3005                         synchronized(emLock){
3006                                 if(em.isOpen()){
3007                                         if(em.getTransaction().isActive()){
3008                                                 em.getTransaction().rollback();
3009                                         }
3010                                         em.close();
3011                                 }
3012                                 if(transactionTimer instanceof Thread){
3013                                         transactionTimer.interrupt();
3014                                 }
3015                         }
3016                 }
3017
3018
3019
3020                 @Override
3021                 public void createGroup(String groupId, String groupName, String groupDescription, String username) {
3022                         logger.debug("deletePolicy(String policyToDeletes) as createGroup("+groupId+", "+groupName+", "+groupDescription+") called");
3023                         if(isNullOrEmpty(groupId, groupName, username)){
3024                                 throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty");
3025                         }
3026                         if(!(groupDescription instanceof String)){
3027                                 groupDescription = "";
3028                         }
3029
3030                         synchronized(emLock){
3031                                 checkBeforeOperationRun();
3032                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3033                                 checkGroupQuery.setParameter("groupId", groupId);
3034                                 checkGroupQuery.setParameter("deleted", false);
3035                                 List<?> checkGroupQueryList;
3036                                 try{
3037                                         checkGroupQueryList = checkGroupQuery.getResultList();
3038                                 } catch(Exception e){
3039                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
3040                                         throw new PersistenceException("Query failed trying to check for existing group");
3041                                 }
3042                                 if(checkGroupQueryList.size() > 0){
3043                                         PolicyLogger.error("The group being added already exists with id "+groupId);
3044                                         throw new PersistenceException("The group being added already exists with id "+groupId);
3045                                 }
3046                                 GroupEntity newGroup = new GroupEntity();
3047                                 em.persist(newGroup);
3048                                 newGroup.setCreatedBy(username);
3049                                 newGroup.setModifiedBy(username);
3050                                 newGroup.setGroupName(groupName);
3051                                 newGroup.setGroupId(groupId);
3052                                 newGroup.setDescription(groupDescription);
3053
3054                                 em.flush();
3055                                 this.groupId = newGroup.getGroupKey();
3056                         }
3057                 }
3058
3059                 @Override
3060                 public void updateGroup(EcompPDPGroup group, String username){
3061                         logger.debug("updateGroup(PDPGroup group) as updateGroup("+group+","+username+") called");
3062                         if(group == null){
3063                                 throw new IllegalArgumentException("PDPGroup group must not be null");
3064                         }
3065                         if(isNullOrEmpty(group.getId(), username)){
3066                                 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
3067                         }
3068
3069                         synchronized(emLock){
3070                                 checkBeforeOperationRun();
3071                                 Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3072                                 getGroupQuery.setParameter("groupId", group.getId());
3073                                 getGroupQuery.setParameter("deleted", false);
3074                                 List<?> getGroupQueryList;
3075                                 try{
3076                                         getGroupQueryList = getGroupQuery.getResultList();
3077                                 } catch(Exception e){
3078                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
3079                                         throw new PersistenceException("Query failed trying to get group "+group.getId()+" for editing");
3080                                 }
3081                                 if(getGroupQueryList.size() < 1){
3082                                         PolicyLogger.error("The group cannot be found to update with id "+group.getId());
3083                                         throw new PersistenceException("The group cannot be found to update with id "+group.getId());
3084                                 } else if(getGroupQueryList.size() > 1){
3085                                         PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
3086                                         throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
3087                                 }
3088                                 GroupEntity groupToUpdate = (GroupEntity)getGroupQueryList.get(0);
3089                                 if(!stringEquals(groupToUpdate.getModifiedBy(), username)){
3090                                         groupToUpdate.setModifiedBy(username);
3091                                 }
3092                                 if(group.getDescription() != null && !stringEquals(group.getDescription(),groupToUpdate.getDescription())){
3093                                         groupToUpdate.setDescription(group.getDescription());
3094                                 }
3095                                 //let's find out what policies have been deleted
3096                                 StdPDPGroup oldGroup = null;
3097                                 try {
3098                                         oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId());
3099                                 } catch (PAPException e1) {
3100                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "We cannot get the group from the papEngine to delete policies");
3101                                 }
3102                                 if(oldGroup == null){
3103                                         PolicyLogger.error("We cannot get the group from the papEngine to delete policies");
3104                                 } else {
3105
3106                                         Set<String> newPolicySet = new HashSet<>(group.getPolicies().size());
3107                                         //a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison
3108                                         for(PDPPolicy pol: group.getPolicies()){
3109                                                 newPolicySet.add(pol.getId());
3110                                         }
3111                                         for(PDPPolicy pol : oldGroup.getPolicies()){
3112                                                 //should be fast since getPolicies uses a HashSet in StdPDPGroup
3113                                                 if(!newPolicySet.contains(pol.getId())){
3114                                                         String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId());
3115                                                         PolicyEntity policyToDelete;
3116                                                         try{
3117                                                                 policyToDelete = getPolicy(scopeAndName[0],scopeAndName[1]);
3118                                                         }catch(Exception e){
3119                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get policy to remove: "+pol.getId());
3120                                                                 throw new PersistenceException("Could not get policy to remove: "+pol.getId());
3121                                                         }
3122                                                         groupToUpdate.getPolicies().remove(policyToDelete);
3123
3124                                                 }
3125                                         }
3126                                 }
3127                                 if(group.getName() != null && !stringEquals(group.getName(),groupToUpdate.getgroupName())){
3128                                         //we need to check if the new id exists in the database
3129                                         String newGroupId = createNewPDPGroupId(group.getName());
3130                                         Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3131                                         checkGroupQuery.setParameter("groupId", newGroupId);
3132                                         checkGroupQuery.setParameter("deleted", false);
3133                                         List<?> checkGroupQueryList;
3134                                         try{
3135                                                 checkGroupQueryList = checkGroupQuery.getResultList();
3136                                         } catch(Exception e){
3137                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
3138                                                 throw new PersistenceException("Query failed trying to check for existing group");
3139                                         }
3140                                         if(checkGroupQueryList.size() != 0){
3141                                                 PolicyLogger.error("The new group name already exists, group id "+newGroupId);
3142                                                 throw new PersistenceException("The new group name already exists, group id "+newGroupId);
3143                                         }
3144                                         groupToUpdate.setGroupId(newGroupId);
3145                                         groupToUpdate.setGroupName(group.getName());
3146                                         this.newGroupId = group.getId();
3147                                 }
3148
3149                                 em.flush();
3150                                 this.groupId = groupToUpdate.getGroupKey();
3151                         }
3152                 }
3153
3154                 @Override
3155                 public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) {
3156                         logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup("+pdpID+", "+groupID+", "+pdpName+", "+pdpDescription+", "+pdpJmxPort+", "+username+") called");
3157                         if(isNullOrEmpty(pdpID, groupID,pdpName,username)){
3158                                 throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty");
3159                         }
3160                         if(!(pdpDescription instanceof String)){
3161                                 pdpDescription = "";
3162                         }
3163                         synchronized(emLock){
3164                                 checkBeforeOperationRun();
3165                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3166                                 checkGroupQuery.setParameter("groupId", groupID);
3167                                 checkGroupQuery.setParameter("deleted", false);
3168                                 List<?> checkGroupQueryList;
3169                                 try{
3170                                         checkGroupQueryList = checkGroupQuery.getResultList();
3171                                 } catch(Exception e){
3172                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()");
3173                                         throw new PersistenceException("Query failed trying to check for existing group");
3174                                 }
3175                                 if(checkGroupQueryList.size() != 1){
3176                                         PolicyLogger.error("The group does not exist");
3177                                         throw new PersistenceException("The group does not exist");
3178                                 }
3179                                 Query checkDuplicateQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
3180                                 checkDuplicateQuery.setParameter("pdpId", pdpID);
3181                                 checkDuplicateQuery.setParameter("deleted", false);
3182                                 List<?> checkDuplicateList;
3183                                 try{
3184                                         checkDuplicateList = checkDuplicateQuery.getResultList();
3185                                 } catch(Exception e){
3186                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()");
3187                                         throw new PersistenceException("Query failed trying to check for duplicate PDP "+pdpID);
3188                                 }
3189                                 PdpEntity newPdp;
3190                                 if(checkDuplicateList.size() > 0){
3191                                         logger.warn("PDP already exists with id "+pdpID);                               
3192                                         newPdp = (PdpEntity)checkDuplicateList.get(0);
3193                                 } else {
3194                                         newPdp = new PdpEntity();
3195                                         em.persist(newPdp);
3196                                 }                       
3197
3198                                 newPdp.setCreatedBy(username);
3199                                 newPdp.setDeleted(false);
3200                                 newPdp.setDescription(pdpDescription);
3201                                 newPdp.setGroup((GroupEntity)checkGroupQueryList.get(0));
3202                                 newPdp.setJmxPort(pdpJmxPort);
3203                                 newPdp.setModifiedBy(username);
3204                                 newPdp.setPdpId(pdpID);
3205                                 newPdp.setPdpName(pdpName);
3206
3207                                 em.flush();
3208                                 this.pdpId = newPdp.getPdpKey();
3209
3210                         }
3211                 }
3212
3213
3214                 @Override
3215                 public void updatePdp(EcompPDP pdp, String username){
3216                         logger.debug("updatePdp(PDP pdp, String username) as updatePdp("+pdp+","+username+") called");
3217                         if(pdp == null){
3218                                 throw new IllegalArgumentException("PDP pdp must not be null");
3219                         }
3220                         if(isNullOrEmpty(pdp.getId(),username)){
3221                                 throw new IllegalArgumentException("pdp.getId() and username must not be null or empty");
3222                         }
3223
3224                         synchronized(emLock){
3225                                 checkBeforeOperationRun();
3226                                 Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
3227                                 getPdpQuery.setParameter("pdpId", pdp.getId());
3228                                 getPdpQuery.setParameter("deleted", false);
3229                                 List<?> getPdpQueryList;
3230                                 try{
3231                                         getPdpQueryList = getPdpQuery.getResultList();
3232                                 } catch(Exception e){
3233                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
3234                                         throw new PersistenceException("Query failed trying to get PDP "+pdp.getId());
3235                                 }
3236                                 if(getPdpQueryList.size() < 1){
3237                                         PolicyLogger.error("The pdp cannot be found to update with id "+pdp.getId());
3238                                         throw new PersistenceException("The pdp cannot be found to update with id "+pdp.getId());
3239                                 } else if(getPdpQueryList.size() > 1){
3240                                         PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
3241                                         throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
3242                                 }
3243                                 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
3244                                 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
3245                                         pdpToUpdate.setModifiedBy(username);
3246                                 }
3247                                 if(pdp.getDescription() != null && !stringEquals(pdp.getDescription(),pdpToUpdate.getDescription())){
3248                                         pdpToUpdate.setDescription(pdp.getDescription());
3249                                 }
3250                                 if(pdp.getName() != null && !stringEquals(pdp.getName(),pdpToUpdate.getPdpName())){
3251                                         pdpToUpdate.setPdpName(pdp.getName());
3252                                 }
3253                                 if(pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())){
3254                                         pdpToUpdate.setJmxPort(pdp.getJmxPort());
3255                                 }
3256
3257                                 em.flush();
3258                                 this.pdpId = pdpToUpdate.getPdpKey();
3259                         }
3260                 }
3261
3262                 @Override
3263                 public void movePdp(EcompPDP pdp, EcompPDPGroup group, String username){
3264                         logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp("+pdp+","+group+","+username+") called");
3265                         if(pdp == null || group == null){
3266                                 throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null");
3267                         }
3268                         if(isNullOrEmpty(username,pdp.getId(),group.getId())){
3269                                 throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty");
3270                         }
3271
3272                         synchronized(emLock){
3273                                 checkBeforeOperationRun();
3274                                 //check if pdp exists
3275                                 Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
3276                                 getPdpQuery.setParameter("pdpId", pdp.getId());
3277                                 getPdpQuery.setParameter("deleted", false);
3278                                 List<?> getPdpQueryList;
3279                                 try{
3280                                         getPdpQueryList = getPdpQuery.getResultList();
3281                                 } catch(Exception e){
3282                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
3283                                         throw new PersistenceException("Query failed trying to get pdp to move with id "+pdp.getId());
3284                                 }
3285                                 if(getPdpQueryList.size() < 1){
3286                                         PolicyLogger.error("The pdp cannot be found to move with id "+pdp.getId());
3287                                         throw new PersistenceException("The pdp cannot be found to move with id "+pdp.getId());
3288                                 } else if(getPdpQueryList.size() > 1){
3289                                         PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
3290                                         throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
3291                                 }
3292
3293                                 //check if new group exists
3294                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3295                                 checkGroupQuery.setParameter("groupId", group.getId());
3296                                 checkGroupQuery.setParameter("deleted", false);
3297                                 List<?> checkGroupQueryList;
3298                                 try{
3299                                         checkGroupQueryList = checkGroupQuery.getResultList();
3300                                 } catch(Exception e){
3301                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group on checkGroupQuery.getResultList()");
3302                                         throw new PersistenceException("Query failed trying to get new group "+group.getId());
3303                                 }
3304                                 if(checkGroupQueryList.size() != 1){
3305                                         PolicyLogger.error("The group "+group.getId()+" does not exist");
3306                                         throw new PersistenceException("The group "+group.getId()+" does not exist");
3307                                 }
3308                                 GroupEntity groupToMoveInto = (GroupEntity)checkGroupQueryList.get(0);
3309                                 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
3310                                 pdpToUpdate.setGroup(groupToMoveInto);
3311                                 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
3312                                         pdpToUpdate.setModifiedBy(username);
3313                                 }
3314
3315                                 em.flush();
3316                                 this.pdpId = pdpToUpdate.getPdpKey();
3317                         }
3318                 }
3319
3320                 @Override
3321                 public void changeDefaultGroup(EcompPDPGroup group, String username){
3322                         logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup("+group+","+username+") called");
3323                         if(group == null){
3324                                 throw new IllegalArgumentException("PDPGroup group must not be null");
3325                         }
3326                         if(isNullOrEmpty(group.getId(),username)){
3327                                 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
3328                         }
3329
3330                         synchronized(emLock){
3331                                 checkBeforeOperationRun();
3332                                 Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3333                                 getGroupQuery.setParameter("groupId", group.getId());
3334                                 getGroupQuery.setParameter("deleted", false);
3335                                 List<?> getGroupQueryList;
3336                                 try{
3337                                         getGroupQueryList = getGroupQuery.getResultList();
3338                                 } catch(Exception e){
3339                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
3340                                         throw new PersistenceException("Query failed trying to get group "+group.getId());
3341                                 }
3342                                 if(getGroupQueryList.size() < 1){
3343                                         PolicyLogger.error("The group cannot be found to set default with id "+group.getId());                          
3344                                         throw new PersistenceException("The group cannot be found to set default with id "+group.getId());
3345                                 } else if(getGroupQueryList.size() > 1){
3346                                         PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
3347                                         throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
3348                                 }
3349                                 GroupEntity newDefaultGroup = (GroupEntity)getGroupQueryList.get(0);
3350                                 newDefaultGroup.setDefaultGroup(true);
3351                                 if(!stringEquals(newDefaultGroup.getModifiedBy(), username)){
3352                                         newDefaultGroup.setModifiedBy(username);
3353                                 }
3354
3355                                 em.flush();
3356                                 this.groupId = newDefaultGroup.getGroupKey();
3357                                 Query setAllGroupsNotDefault = em.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g.groupKey<>:groupKey");
3358                                 //not going to set modified by for all groups
3359                                 setAllGroupsNotDefault.setParameter("defaultGroup", false);
3360                                 setAllGroupsNotDefault.setParameter("deleted", false);
3361                                 setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey());
3362                                 try{
3363                                         logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default");
3364                                 } catch(Exception e){
3365                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on setAllGroupsNotDefault.executeUpdate()");
3366                                         throw new PersistenceException("Could not set all other groups default to false");
3367                                 }
3368
3369                                 em.flush();
3370                         }
3371                 }
3372
3373
3374                 @Override
3375                 public void deleteGroup(EcompPDPGroup group, EcompPDPGroup moveToGroup, String username) throws PAPException {
3376                         logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called");
3377                         if(group == null){
3378                                 throw new IllegalArgumentException("PDPGroup group cannot be null");
3379                         }
3380                         if(isNullOrEmpty(username,group.getId())){
3381                                 throw new IllegalArgumentException("group.getId() and and username must not be null or empty");
3382                         }
3383
3384                         if(group.isDefaultGroup()){
3385                                 PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be.");
3386                                 throw new PAPException("You cannot delete the default group.");
3387                         }
3388                         synchronized(emLock){
3389                                 checkBeforeOperationRun();
3390                                 Query deleteGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3391                                 deleteGroupQuery.setParameter("groupId", group.getId());
3392                                 deleteGroupQuery.setParameter("deleted", false);
3393                                 List<?> deleteGroupQueryList;
3394                                 try{
3395                                         deleteGroupQueryList = deleteGroupQuery.getResultList();
3396                                 } catch(Exception e){
3397                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()");
3398                                         throw new PersistenceException("Query failed trying to check if group exists");
3399                                 }
3400                                 if(deleteGroupQueryList.size() < 1){
3401                                         logger.warn("The group could not be found with id " + group.getId());
3402                                         return;
3403                                 } else if(deleteGroupQueryList.size() > 1){
3404                                         PolicyLogger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
3405                                         throw new PersistenceException("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
3406                                 }                               
3407
3408                                 Query pdpsInGroupQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted");
3409                                 pdpsInGroupQuery.setParameter("group", ((GroupEntity)deleteGroupQueryList.get(0)));
3410                                 pdpsInGroupQuery.setParameter("deleted", false);
3411                                 List<?> pdpsInGroupList;
3412                                 try{
3413                                         pdpsInGroupList = pdpsInGroupQuery.getResultList();
3414                                 } catch(Exception e){
3415                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()");
3416                                         throw new PersistenceException("Query failed trying to get PDPs in group");
3417                                 }
3418                                 if(pdpsInGroupList.size() > 0){
3419                                         if(moveToGroup != null){
3420                                                 Query checkMoveToGroupQuery = em.createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted");
3421                                                 checkMoveToGroupQuery.setParameter("groupId", moveToGroup.getId());
3422                                                 checkMoveToGroupQuery.setParameter("deleted", false);
3423                                                 List<?> checkMoveToGroupList;
3424                                                 try{
3425                                                         checkMoveToGroupList = checkMoveToGroupQuery.getResultList();
3426                                                 } catch(Exception e){
3427                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()");
3428                                                         throw new PersistenceException("Query failed trying to check if group exists");
3429                                                 }
3430                                                 if(checkMoveToGroupList.size() < 1){
3431                                                         PolicyLogger.error("The group could not be found with id " + moveToGroup.getId());
3432                                                         throw new PersistenceException("The group could not be found with id " + moveToGroup.getId());
3433                                                 } else if(checkMoveToGroupList.size() > 1){
3434                                                         PolicyLogger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
3435                                                         throw new PersistenceException("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
3436                                                 } else {
3437                                                         GroupEntity newGroup = (GroupEntity)checkMoveToGroupList.get(0);
3438                                                         for(Object pdpObject : pdpsInGroupList){
3439                                                                 PdpEntity pdp = (PdpEntity)pdpObject;
3440                                                                 pdp.setGroup(newGroup);
3441                                                                 if(!stringEquals(pdp.getModifiedBy(),username)){
3442                                                                         pdp.setModifiedBy(username);
3443                                                                 }
3444                                                                 try{
3445
3446                                                                         em.flush();
3447                                                                         this.newGroupId = newGroup.getGroupId();
3448                                                                 } catch(PersistenceException e){
3449                                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PersistenceException trying to set pdp group to null on em.flush()");
3450                                                                         throw new PersistenceException("Query failed trying to set pdp group to ");
3451                                                                 }
3452                                                         }
3453                                                 }
3454                                         } else {
3455                                                 PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to");
3456                                                 throw new PAPException("Group has PDPs. Must provide a group for them to move to");
3457                                         }
3458                                 } 
3459
3460                                 //delete group here
3461                                 GroupEntity groupToDelete = (GroupEntity)deleteGroupQueryList.get(0);
3462                                 groupToDelete.setDeleted(true);
3463                                 if(!stringEquals(groupToDelete.getModifiedBy(), username)){
3464                                         groupToDelete.setModifiedBy(username);
3465                                 }
3466                                 em.flush();
3467                                 this.groupId = groupToDelete.getGroupKey();
3468                         }
3469                 }
3470
3471                 @Override
3472                 public void addPolicyToGroup(String groupID, String policyID, String username) {
3473                         logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called");
3474                         if(isNullOrEmpty(groupID, policyID, username)){
3475                                 throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty");
3476                         }
3477                         synchronized(emLock){
3478                                 checkBeforeOperationRun();
3479                                 //check if group exists
3480                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
3481                                 groupQuery.setParameter("groupId", groupID);
3482                                 groupQuery.setParameter("deleted", false);
3483                                 List<?> groupQueryList;
3484                                 try{
3485                                         groupQueryList = groupQuery.getResultList();
3486                                 }catch(Exception e){
3487                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()");
3488                                         throw new PersistenceException("Query failed trying to check if group "+groupID+" exists");
3489                                 }
3490                                 if(groupQueryList.size() < 1){
3491                                         PolicyLogger.error("Group policy is being added to does not exist with id "+groupID);
3492                                         throw new PersistenceException("Group policy is being added to does not exist with id "+groupID);
3493                                 } else if(groupQueryList.size() > 1){
3494                                         PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
3495                                         throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
3496                                 }
3497                                 //we need to convert the form of the policy id that is used groups into the form that is used 
3498                                 //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml)
3499                                 String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID);                     
3500                                 Query policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p.deleted=:deleted");
3501                                 policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]);
3502                                 policyQuery.setParameter("scope", policyNameScopeAndVersion[1]);                        
3503                                 policyQuery.setParameter("deleted", false);
3504                                 List<?> policyQueryList;
3505                                 try{
3506                                         policyQueryList = policyQuery.getResultList();
3507                                 } catch(Exception e){
3508                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if policy exists policyQuery.getResultList()");
3509                                         throw new PersistenceException("Query failed trying to check if policy "+policyNameScopeAndVersion[0]+" exists");
3510                                 }
3511                                 if(policyQueryList.size() < 1){
3512                                         PolicyLogger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
3513                                         throw new PersistenceException("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);                          
3514                                 } else if(policyQueryList.size() > 1){
3515                                         PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
3516                                         throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
3517                                 }
3518                                 GroupEntity group = (GroupEntity)groupQueryList.get(0);
3519                                 PolicyEntity policy = (PolicyEntity)policyQueryList.get(0);
3520                     Iterator<PolicyEntity> policyIt = group.getPolicies().iterator();
3521                     String policyName = getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0];
3522                     try{
3523                     while(policyIt.hasNext()){
3524                         PolicyEntity pol = policyIt.next();
3525                         if(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){
3526                             policyIt.remove();
3527                         }
3528                     }
3529                     }catch(Exception e){
3530                         PolicyLogger.error("Could not delete old versions for policy "+policy.getPolicyName()+", ID: "+policy.getPolicyId());
3531                     }
3532                                 group.addPolicyToGroup(policy);
3533                                 em.flush();
3534                         }
3535                 }
3536
3537                 //this means delete pdp not just remove from group
3538                 @Override
3539                 public void removePdpFromGroup(String pdpID, String username) {
3540                         logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup("+pdpID+","+username+") called");
3541                         if(isNullOrEmpty(pdpID,username)){
3542                                 throw new IllegalArgumentException("pdpID and username must not be null or empty");
3543                         }
3544                         synchronized(emLock){
3545                                 checkBeforeOperationRun();
3546                                 Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
3547                                 pdpQuery.setParameter("pdpId", pdpID);
3548                                 pdpQuery.setParameter("deleted", false);
3549                                 List<?> pdpList;
3550                                 try{
3551                                         pdpList = pdpQuery.getResultList();
3552                                 } catch(Exception e){
3553                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if pdp exists  pdpQuery.getResultList()");
3554                                         throw new PersistenceException("Query failed trying to check if pdp "+pdpID+" exists");
3555                                 }
3556                                 if(pdpList.size() > 1){
3557                                         PolicyLogger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
3558                                         throw new PersistenceException("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
3559                                 } else if(pdpList.size() < 1){
3560                                         PolicyLogger.error("Pdp being removed does not exist with id "+pdpID);
3561                                         return;
3562                                 }
3563                                 PdpEntity pdp = (PdpEntity)pdpList.get(0);
3564                                 pdp.setGroup(null);
3565                                 if(!stringEquals(pdp.getModifiedBy(),username)){
3566                                         pdp.setModifiedBy(username);
3567                                 }
3568                                 pdp.setDeleted(true);
3569
3570                                 em.flush();
3571                                 this.pdpId = pdp.getPdpKey();
3572                         }
3573                 }
3574         }
3575
3576
3577
3578         private static String getDefaultWorkspace(){
3579                 return "admin";
3580         }
3581
3582         private PolicyDBDao(){
3583
3584         }
3585         
3586         public static PolicyDBDaoTestClass getPolicyDBDaoTestClass(){
3587                 return new PolicyDBDao().new PolicyDBDaoTestClass();
3588         }
3589         
3590         final class PolicyDBDaoTestClass {
3591                 String[] getScopeAndNameAndType(final String path){
3592                         return PolicyDBDao.getScopeAndNameAndType(path);
3593                 }
3594                 String getGitPath(){
3595                         return PolicyDBDao.getGitPath();
3596                 }
3597                 String getConfigFile(String filename, String scope, PolicyRestAdapter policy){
3598                         return PolicyDBDao.this.getConfigFile(filename, policy);
3599                 }
3600                 String computeScope(String fullPath, String pathToExclude){
3601                         return PolicyDBDao.computeScope(fullPath, pathToExclude);
3602                 }
3603                 String encryptPassword(String password) throws Exception{
3604                         return PolicyDBDao.encryptPassword(password);
3605                 }
3606                 String decryptPassword(String password) throws Exception{
3607                         return PolicyDBDao.decryptPassword(password);
3608                 }
3609                 String getDescriptionFromXacml(String xacmlData){
3610                         return PolicyDBDao.getDescriptionFromXacml(xacmlData);
3611                 }
3612         String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){
3613             return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName);
3614         }
3615         }
3616
3617 }