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