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