[Policy-20] getConfig & Policy resolved blockers
[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.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.FileWriter;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.StringReader;
31 import java.net.HttpURLConnection;
32 import java.net.MalformedURLException;
33 import java.net.ProtocolException;
34 import java.net.URL;
35 import java.nio.charset.StandardCharsets;
36 import java.nio.file.Files;
37 import java.nio.file.InvalidPathException;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.security.Key;
41 import java.util.Base64;
42 import java.util.Date;
43 import java.util.HashMap;
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.LinkedList;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Set;
50 import java.util.UUID;
51
52 import javax.crypto.Cipher;
53 import javax.crypto.spec.SecretKeySpec;
54 import javax.persistence.EntityManager;
55 import javax.persistence.EntityManagerFactory;
56 import javax.persistence.LockModeType;
57 import javax.persistence.PersistenceException;
58 import javax.persistence.Query;
59 import javax.persistence.RollbackException;
60 import javax.xml.parsers.DocumentBuilder;
61 import javax.xml.parsers.DocumentBuilderFactory;
62 import javax.xml.xpath.XPath;
63 import javax.xml.xpath.XPathFactory;
64
65 import org.apache.commons.io.FilenameUtils;
66 import org.apache.commons.io.IOUtils;
67 import org.openecomp.policy.common.logging.eelf.MessageCodes;
68 import org.openecomp.policy.common.logging.eelf.PolicyLogger;
69 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
70 import org.openecomp.policy.common.logging.flexlogger.Logger;
71 import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet;
72 import org.openecomp.policy.rest.XACMLRestProperties;
73 import org.openecomp.policy.rest.adapter.PolicyRestAdapter;
74 import org.openecomp.policy.rest.jpa.ActionBodyEntity;
75 import org.openecomp.policy.rest.jpa.ConfigurationDataEntity;
76 import org.openecomp.policy.rest.jpa.DatabaseLockEntity;
77 import org.openecomp.policy.rest.jpa.GroupEntity;
78 import org.openecomp.policy.rest.jpa.PdpEntity;
79 import org.openecomp.policy.rest.jpa.PolicyDBDaoEntity;
80 import org.openecomp.policy.rest.jpa.PolicyEntity;
81 import org.openecomp.policy.rest.util.Webapps;
82 import org.openecomp.policy.xacml.api.pap.EcompPDP;
83 import org.openecomp.policy.xacml.api.pap.EcompPDPGroup;
84 import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine;
85 import org.openecomp.policy.xacml.std.pap.StdPDPGroup;
86 import org.openecomp.policy.xacml.std.pap.StdPDPPolicy;
87 import org.openecomp.policy.xacml.util.XACMLPolicyWriter;
88 import org.w3c.dom.Document;
89 import org.xml.sax.InputSource;
90
91 import com.att.research.xacml.api.pap.PAPException;
92 import com.att.research.xacml.api.pap.PDP;
93 import com.att.research.xacml.api.pap.PDPPolicy;
94 import com.att.research.xacml.util.XACMLProperties;
95
96 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
97
98 public class PolicyDBDao {
99         private static final Logger logger      = FlexLogger.getLogger(PolicyDBDao.class);              
100         private List<?> otherServers;
101         private EntityManagerFactory emf;
102         private static PolicyDBDao currentInstance = null;
103         private PAPPolicyEngine papEngine;
104
105         public static final String JSON_CONFIG = "JSON";
106         public static final String XML_CONFIG = "XML";
107         public static final String PROPERTIES_CONFIG = "PROPERTIES";
108         public static final String OTHER_CONFIG = "OTHER";
109         public static final String AUDIT_USER = "audit";
110
111         /**
112          * Get an instance of a PolicyDBDao. It creates one if it does not exist.
113          * Only one instance is allowed to be created per server.
114          * @param emf The EntityFactoryManager to be used for database connections
115          * @return The new instance of PolicyDBDao or throw exception if the given emf is null.
116          * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this.
117          */
118         public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) throws Exception{
119                 logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called");
120                 if(currentInstance == null){
121                         if(emf != null){
122                                 currentInstance = new PolicyDBDao(emf);
123                                 return currentInstance;
124                         }
125                         throw new IllegalStateException("The EntityManagerFactory is Null");
126                 }
127                 return currentInstance;
128         }
129
130         /**
131          * Gets the current instance of PolicyDBDao. 
132          * @return The instance of PolicyDBDao or throws exception if the given instance is null.
133          * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this.
134          */
135         public static PolicyDBDao getPolicyDBDaoInstance() throws Exception{
136                 logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called");
137                 if(currentInstance != null){
138                         return currentInstance;
139                 }
140                 throw new IllegalStateException("The PolicyDBDao.currentInstance is Null.  Use getPolicyDBDao(EntityManagerFactory emf)");
141         }
142         public void setPapEngine(PAPPolicyEngine papEngine2){
143                 this.papEngine = (PAPPolicyEngine) papEngine2;
144         }
145         private PolicyDBDao(EntityManagerFactory emf){
146                 logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao("+emf+") called");
147                 this.emf = emf;
148
149                 //not needed in this release
150                 if(!register()){
151                         PolicyLogger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
152                 }
153
154                 otherServers = getRemotePolicyDBDaoList();
155                 if(logger.isDebugEnabled()){
156                         logger.debug("Number of remote PolicyDBDao instances: "+otherServers.size());
157                 }
158                 if(otherServers.isEmpty()){
159                         logger.warn("List of PolicyDBDao servers is empty or could not be retrieved");
160                 }
161         }
162
163         //not static because we are going to be using the instance's emf
164         //waitTime in ms to wait for lock, or -1 to wait forever (no)
165         private void startTransactionSynced(EntityManager entityMgr,int waitTime){
166                 logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as "
167                                 + "\n   startTransactionSynced("+entityMgr+","+waitTime+") called\n\n");
168                 DatabaseLockEntity lock = null;         
169
170                 entityMgr.setProperty("javax.persistence.query.timeout", waitTime);
171                 entityMgr.getTransaction().begin();
172
173                 if(logger.isDebugEnabled()){
174                         Map<String,Object> properties = entityMgr.getProperties();
175                         logger.debug("\n\nstartTransactionSynced():"
176                                         + "\n   entityManager.getProperties() = " + properties 
177                                         + "\n\n");
178                 }
179                 try{
180                         if(logger.isDebugEnabled()){
181                                 logger.debug("\n\nstartTransactionSynced():"
182                                                 + "\n   ATTEMPT to get the DB lock"
183                                                 + "\n\n");
184                         }
185                         lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE);
186                         if(logger.isDebugEnabled()){
187                                 logger.debug("\n\nstartTransactionSynced():"
188                                                 + "\n   GOT the DB lock"
189                                                 + "\n\n");
190                         }
191                 } catch(Exception e){
192                         System.out.println("Could not get lock entity");
193                         logger.error("Exception Occured"+e);
194                 }
195                 if(lock == null){
196                         throw new IllegalStateException("The lock row does not exist in the table. Please create a primary key with value = 1.");       
197                 }
198
199         }
200         /**
201          * Gets the list of other registered PolicyDBDaos from the database
202          * @return List (type PolicyDBDaoEntity) of other PolicyDBDaos
203          */
204         private List<?> getRemotePolicyDBDaoList(){
205                 logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called");
206                 List<?> policyDBDaoEntityList = new LinkedList<>();
207                 EntityManager em = emf.createEntityManager();
208                 startTransactionSynced(em, 1000);
209                 try{                                            
210                         Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll");                     
211                         policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList();
212
213                 } catch(Exception e){
214                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception querying for other registered PolicyDBDaos");
215                         logger.warn("List of remote PolicyDBDaos will be empty");
216                 }
217                 try{
218                         em.getTransaction().commit();
219                 } catch(Exception e){
220                         try{
221                                 em.getTransaction().rollback();
222                         } catch(Exception e2){
223
224                         }
225                 }
226                 em.close();
227                 return policyDBDaoEntityList;
228         }
229
230         public PolicyDBDaoTransaction getNewTransaction(){
231                 logger.debug("getNewTransaction() as getNewTransaction() called");
232                 return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance());
233         }
234
235         /*
236          * Because the normal transactions are not used in audits, we can use the same transaction
237          * mechanism to get a transaction and obtain the emlock and the DB lock.  We just need to
238          * provide different transaction timeout values in ms because the audit will run longer
239          * than normal transactions.
240          */
241         public PolicyDBDaoTransaction getNewAuditTransaction(){
242                 logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called");
243                 //Use the standard transaction wait time in ms
244                 int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
245                 //Use the (extended) audit timeout time in ms
246                 int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); 
247                 return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs));
248         }
249
250
251         /**
252          * Checks if two strings are equal. Null strings ARE allowed.
253          * @param one A String or null to compare
254          * @param two A String or null to compare
255          */
256         private static boolean stringEquals(String one, String two){
257                 logger.debug("stringEquals(String one, String two) as stringEquals("+one+", "+two+") called");
258                 if(one == null && two == null){
259                         return true;
260                 }
261                 if(one == null || two == null){
262                         return false;
263                 }
264                 return one.equals(two);
265         }
266
267         /**
268          * Computes the scope in dotted format based on an absolute path and a path that divides the scope.
269          * @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)
270          * @param pathToExclude The path that acts as a division between the scope and the other folders
271          * @return The scope in dotted format (org.openecomp)
272          */
273         private static String computeScope(String fullPath, String pathToExclude){
274                 logger.debug("computeScope(String fullPath, String pathToExclude) as computeScope("+fullPath+", "+pathToExclude+") called");
275                 int excludeIndex = fullPath.indexOf(pathToExclude);
276                 String scopePath = fullPath.substring(excludeIndex+pathToExclude.length());
277                 String scope = scopePath.replace('\\', '.');
278                 scope = scope.replace('/', '.');
279                 if(scope.charAt(0) == '.'){
280                         scope = scope.substring(1);
281                 }
282                 if(scope.charAt(scope.length()-1) == '.'){
283                         scope = scope.substring(0, scope.length()-1);
284                 }
285                 return scope;
286         }
287
288         /**
289          * Returns the url of this local pap server, removing the username and password, if they are present
290          * @return The url of this local pap server
291          */
292         private String[] getPapUrlUserPass(){
293                 logger.debug("getPapUrl() as getPapUrl() called");
294                 String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
295                 if(url == null){
296                         return null;
297                 }
298                 return splitPapUrlUserPass(url);
299
300
301         }
302         private String[] splitPapUrlUserPass(String url){
303                 String[] urlUserPass = new String[3];
304                 String[] commaSplit = url.split(",");
305                 urlUserPass[0] = commaSplit[0];
306                 if(commaSplit.length > 2){
307                         urlUserPass[1] = commaSplit[1];
308                         urlUserPass[2] = commaSplit[2];
309                 }
310                 if(urlUserPass[1] == null || urlUserPass[1].equals("")){
311                         String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
312                         if(usernamePropertyValue != null){
313                                 urlUserPass[1] = usernamePropertyValue;
314                         }
315                 }
316                 if(urlUserPass[2] == null || urlUserPass[2].equals("")){
317                         String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
318                         if(passwordPropertyValue != null){
319                                 urlUserPass[2] = passwordPropertyValue;
320                         }
321                 }
322                 //if there is no comma, for some reason there is no username and password, so don't try to cut them off
323                 return urlUserPass;
324         }
325
326         private static String encryptPassword(String password) throws Exception{
327                 Cipher cipher = Cipher.getInstance("AES");              
328                 cipher.init(Cipher.ENCRYPT_MODE, aesKey());
329                 byte[] encryption = cipher.doFinal(password.getBytes("UTF-8"));
330                 System.out.println(encryption);
331                 return new String(Base64.getMimeEncoder().encode(encryption),"UTF-8");
332         }
333
334         private static String decryptPassword(String encryptedPassword) throws Exception{
335                 Cipher cipher = Cipher.getInstance("AES");
336                 cipher.init(Cipher.DECRYPT_MODE, aesKey());
337                 byte[] password = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword.getBytes("UTF-8")));
338                 return new String(password,"UTF-8");
339         }
340         private static Key aesKey(){
341                 byte[] aesValue = (new String("njrmbklcxtoplawf")).getBytes();
342                 return new SecretKeySpec(aesValue,"AES");
343         }
344         /**
345          * Register the PolicyDBDao instance in the PolicyDBDaoEntity table
346          * @return Boolean, were we able to register?
347          */
348         private boolean register(){
349                 logger.debug("register() as register() called");
350                 String[] url = getPapUrlUserPass();
351                 EntityManager em = emf.createEntityManager();
352                 try{
353                         startTransactionSynced(em, 1000);
354                 } catch(IllegalStateException e){
355                         logger.debug ("\nPolicyDBDao.register() caught an IllegalStateException: \n" +e + "\n");
356                         DatabaseLockEntity lock;
357                         lock = em.find(DatabaseLockEntity.class, 1);
358                         if(lock==null){                         
359                                 lock = new DatabaseLockEntity();
360                                 em.persist(lock);
361                                 lock.setKey(1);
362                                 try{
363                                         em.flush();
364                                         em.getTransaction().commit();
365                                         em.close();                                     
366                                 } catch(Exception e2){
367                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "COULD NOT CREATE DATABASELOCK ROW.  WILL TRY ONE MORE TIME");
368                                 }
369                                 em = null;
370                                 em = emf.createEntityManager();
371                                 try{
372                                         startTransactionSynced(em, 1000);
373                                 } catch(Exception e3){
374                                         String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING";
375                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, "PolicyDBDao", msg);
376                                         throw new IllegalStateException("msg" + "\n" + e3);
377                                 }
378                         }
379                 }
380                 logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n");
381                 PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]);
382                 Query getPolicyDBDaoEntityQuery = em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url");
383                 getPolicyDBDaoEntityQuery.setParameter("url", url[0]);
384                 if(foundPolicyDBDaoEntity == null){
385                         PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity();
386                         em.persist(newPolicyDBDaoEntity);
387                         newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]);
388                         newPolicyDBDaoEntity.setDescription("PAP server at "+url[0]);
389                         newPolicyDBDaoEntity.setUsername(url[1]);
390                         try{
391                                 newPolicyDBDaoEntity.setPassword(encryptPassword(url[2]));
392                         } catch(Exception e){
393                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
394                         }
395                         try{
396                                 em.getTransaction().commit();
397                         } catch(Exception e){
398                                 try{
399                                         em.getTransaction().rollback();
400                                 } catch(Exception e2){
401                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not add new PolicyDBDao to the database");
402                                 }
403                         }
404                 } else {
405                         //just want to update in order to change modified date
406                         String encryptedPassword = null;
407                         try{
408                                 encryptedPassword = encryptPassword(url[2]);
409                         } catch(Exception e){
410                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password");
411                         }
412                         if(url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())){
413                                 foundPolicyDBDaoEntity.setUsername(url[1]);
414                         }
415                         if(encryptedPassword != null && !stringEquals(encryptedPassword, foundPolicyDBDaoEntity.getPassword())){
416                                 foundPolicyDBDaoEntity.setPassword(encryptedPassword);
417                         }
418                         foundPolicyDBDaoEntity.preUpdate();
419                         try{
420                                 em.getTransaction().commit();
421                         } catch(Exception e){
422                                 try{
423                                         em.getTransaction().rollback();
424                                 } catch(Exception e2){
425                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not update PolicyDBDao in the database");
426                                 }
427                         }
428                 }
429                 em.close();
430                 logger.debug("\nPolicyDBDao.register(). Success!!\n");
431                 return true;
432         }
433         public void notifyOthers(long entityId,String entityType){
434                 notifyOthers(entityId,entityType,null);
435         }
436         public void notifyOthers(long entityId, String entityType, String newGroupId){
437                 logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers("+entityId+","+entityType+","+newGroupId+") called");             
438                 LinkedList<Thread> notifyThreads = new LinkedList<>();
439
440                 //we're going to run notifications in parallel threads to speed things up
441                 for(Object obj : otherServers){
442
443                         Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId));
444
445                         newNotifyThread.start();
446
447                         notifyThreads.add(newNotifyThread);
448
449                 }
450                 //we want to wait for all notifications to complete or timeout before we unlock the interface and allow more changes
451                 for(Thread t : notifyThreads){
452                         try {
453                                 t.join();
454                         } catch (Exception e) {
455                                 logger.warn("Could not join a notifcation thread" + e);
456                         }
457                 }
458
459
460         }
461
462         private class NotifyOtherThread implements Runnable {
463                 public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId){
464                         this.obj = obj;
465                         this.entityId = entityId;
466                         this.entityType = entityType;
467                         this.newGroupId = newGroupId;
468                 }
469                 private Object obj;
470                 private long entityId;
471                 private String entityType;
472                 private String newGroupId;
473                 @Override
474                 public void run(){
475                         //naming of 'o' is for backwards compatibility with the rest of the function
476                         PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity)obj;
477                         String o = dbdEntity.getPolicyDBDaoUrl();
478                         String username = dbdEntity.getUsername();
479                         String password;
480                         try{
481                                 password = decryptPassword(dbdEntity.getPassword());
482                         } catch(Exception e){
483                                 //if we can't decrypt, might as well try it anyway
484                                 password = dbdEntity.getPassword();
485                         }
486                         Base64.Encoder encoder = Base64.getEncoder();                   
487                         String encoding = encoder.encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));
488                         HttpURLConnection connection = null;
489                         UUID requestID = UUID.randomUUID();
490                         URL url;
491                         try {
492                                 String papUrl = getPapUrlUserPass()[0];
493                                 if(papUrl == null){
494                                         papUrl = "undefined";
495                                 }
496                                 logger.debug("We are going to try to notify "+o);
497                                 //is this our own url?
498                                 String ourUrl = o;
499                                 try{
500                                         ourUrl = splitPapUrlUserPass((String)o)[0];
501                                 }catch(Exception e){
502                                         ourUrl = o;
503                                 }
504                                 if(o == null){
505                                         o = "undefined";
506                                 }
507                                 if(papUrl.equals(ourUrl)){
508                                         logger.debug(((String)o)+" is our url, skipping notify");
509                                         return;
510                                 }
511                                 if(newGroupId == null){
512                                         url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType);
513                                 } else {
514                                         url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType+"&extradata="+newGroupId);
515                                 }
516                         } catch (MalformedURLException e) {
517                                 logger.warn("Caught MalformedURLException on: new URL()", e);
518                                 return;
519                         }
520                         //
521                         // Open up the connection
522                         //
523                         logger.debug("Connecting with url: "+url);
524                         try {
525                                 connection = (HttpURLConnection)url.openConnection();
526                         } catch (Exception e) {
527                                 logger.warn("Caught exception on: url.openConnection()",e);
528                                 return;
529                         }
530                         //
531                         // Setup our method and headers
532                         //
533                         try {
534                                 connection.setRequestMethod("PUT");
535                         } catch (ProtocolException e) {
536                                 //why would this error ever occur?
537                                 logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");",e);                     
538                                 return;
539                         }
540                         connection.setRequestProperty("Authorization", "Basic " + encoding);
541                         connection.setRequestProperty("Accept", "text/x-java-properties");
542                         connection.setRequestProperty("Content-Type", "text/x-java-properties");                                        
543                         connection.setRequestProperty("requestID", requestID.toString());
544                         int readTimeout;
545                         try{
546                                 readTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT));
547
548                         } catch(Exception e){
549                                 logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default.");
550                                 readTimeout = 10000;
551                         }
552                         connection.setReadTimeout(readTimeout);
553                         connection.setConnectTimeout(readTimeout);
554                         connection.setUseCaches(false);
555                         //
556                         // Adding this in. It seems the HttpUrlConnection class does NOT
557                         // properly forward our headers for POST re-direction. It does so
558                         // for a GET re-direction.
559                         //
560                         // So we need to handle this ourselves.
561                         //
562                         connection.setInstanceFollowRedirects(false);
563                         connection.setDoOutput(true);
564                         connection.setDoInput(true);
565                         try {
566                                 connection.connect();
567                         } catch (Exception e) {
568                                 logger.warn("Caught exception on: connection.connect()",e);
569                                 return;
570                         }
571                         try {
572                                 if (connection.getResponseCode() == 200) {
573                                         logger.info("Received response 200 from pap server on notify");
574                                         //notified = true;
575                                 } else {
576                                         logger.warn("connection response code not 200, received: "+connection.getResponseCode());
577                                 }
578                         } catch (Exception e) {
579                                 logger.warn("Caught Exception on: connection.getResponseCode() ", e);
580                         }
581
582
583                         connection.disconnect();
584                 }
585         }
586
587         private static String evaluateXPath(String expression, String xml) {
588                 InputSource source = new InputSource(new StringReader(xml));
589
590                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
591                 String description = "";
592                 try{
593                         DocumentBuilder db = dbf.newDocumentBuilder();
594                         Document document = db.parse(source);
595
596                         XPathFactory xpathFactory = XPathFactory.newInstance();
597                         XPath xpath = xpathFactory.newXPath();
598
599
600                         description = xpath.evaluate(expression, document);             
601                 }catch(Exception e){
602                         logger.error("Exception Occured while evaluating path"+e);
603                 }
604
605                 return description;
606         }
607
608         private static String getDescriptionFromXacml(String xacmlData){
609                 String openTag = "<Description>";
610                 String closeTag = "</Description>";
611                 int descIndex = xacmlData.indexOf(openTag);
612                 int endDescIndex = xacmlData.indexOf(closeTag);
613                 String desc = xacmlData.substring(descIndex+openTag.length(),endDescIndex);
614                 return desc;
615         }
616         
617         private final String POLICY_NOTIFICATION = "policy";
618         private final String PDP_NOTIFICATION = "pdp";
619         private final String GROUP_NOTIFICATION = "group";
620         public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, XACMLPapServlet xacmlPapServlet){
621                 logger.info("DBDao url: " + url + " has reported an update on "+entityType+" entity "+entityId);                
622                 PolicyDBDaoTransaction transaction = this.getNewTransaction();
623                 //although its named retries, this is the total number of tries
624                 int retries;
625                 try{
626                         retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INCOMINGNOTIFICATION_TRIES));
627
628                 } catch(Exception e){
629                         logger.error("xacml.rest.pap.incomingnotification.tries property not set, using a default of 3."+e);
630                         retries = 3;
631                 }
632                 //if someone sets it to some dumb value, we need to make sure it will try at least once
633                 if(retries < 1){
634                         retries = 1;
635                 }
636                 int pauseBetweenRetries = 1000;
637                 switch(entityType){     
638
639                 case POLICY_NOTIFICATION:
640                         for(int i=0; i<retries;i++){
641                                 try{
642                                         handleIncomingPolicyChange(url, entityId,extraData);
643                                         break;
644                                 } catch(Exception e){
645                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")");
646                                 }
647                                 try{
648                                         Thread.sleep(pauseBetweenRetries);
649                                 }catch(InterruptedException ie){
650                                         break;
651                                 }
652                         }
653                         break;
654                 case PDP_NOTIFICATION:
655                         for(int i=0; i<retries;i++){
656                                 try{
657                                         handleIncomingPdpChange(url, entityId, transaction);
658                                         break;
659                                 } catch(Exception e){
660                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")");
661                                 }
662                                 try{
663                                         Thread.sleep(pauseBetweenRetries);
664                                 }catch(InterruptedException ie){
665                                         break;
666                                 }
667                         }
668                         break;
669                 case GROUP_NOTIFICATION:
670                         for(int i=0; i<retries;i++){
671                                 try{
672                                         handleIncomingGroupChange(url, entityId, extraData, transaction, xacmlPapServlet);
673                                         break;
674                                 }catch(Exception e){
675                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")");
676                                 }
677                                 try{
678                                         Thread.sleep(pauseBetweenRetries);
679                                 }catch(InterruptedException ie){
680                                         break;
681                                 }
682                         }
683                         break;          
684                 }
685                 //no changes should be being made in this function, we still need to close
686                 transaction.rollbackTransaction();
687         }
688         private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException{
689                 GroupEntity groupRecord = null;
690                 long groupIdLong = -1;
691                 try{
692                         groupIdLong = Long.parseLong(groupId);
693                 } catch(NumberFormatException e){
694                         throw new IllegalArgumentException("groupId "+groupId+" cannot be parsed into a long");
695                 }
696                 try{
697                         groupRecord = transaction.getGroup(groupIdLong);
698                 } catch(Exception e){
699                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");");
700                         throw new PAPException("Could not get local group "+groupIdLong);
701                 }
702                 if(groupRecord == null){
703                         throw new PersistenceException("The group record returned is null");
704                 }
705                 //compare to local fs
706                 //does group folder exist
707                 EcompPDPGroup localGroup = null;
708                 try {
709                         localGroup = papEngine.getGroup(groupRecord.getGroupId());
710                 } catch (Exception e) {
711                         logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+groupId+");",e);
712                 }
713                 if(localGroup == null && extraData != null){
714                         //here we can try to load an old group id from the extraData
715                         try{
716                                 localGroup = papEngine.getGroup(extraData);
717                         }catch(Exception e){
718                                 logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+extraData+");",e);
719                         }
720                 }
721                 if(localGroup != null && groupRecord.isDeleted()){
722                         EcompPDPGroup newLocalGroup = null;
723                         if(extraData != null){
724                                 try {
725                                         newLocalGroup = papEngine.getGroup(extraData);
726                                 } catch (PAPException e) {
727                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");");
728                                 }
729                         }
730                         try {
731                                 papEngine.removeGroup(localGroup, newLocalGroup);
732                         } catch (NullPointerException | PAPException e) {
733                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");");
734                                 throw new PAPException("Could not remove group "+groupId);
735                         }
736                 }
737                 else if(localGroup == null){
738                         //creating a new group
739                         try {
740                                 papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());
741                         } catch (NullPointerException | PAPException e) {
742                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());");
743                                 throw new PAPException("Could not create group "+groupRecord);
744                         }
745                         try {
746                                 localGroup = papEngine.getGroup(groupRecord.getGroupId());
747                         } catch (PAPException e1) {
748                                 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");
749                                 return;
750                         }
751                         //add possible pdps to group
752                         List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId()));
753                         for(Object pdpO : pdpsInGroup){
754                                 PdpEntity pdp = (PdpEntity)pdpO;
755                                 try {
756                                         papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());
757                                 } catch (NullPointerException | PAPException e) {
758                                         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());");
759                                         throw new PAPException("Could not create pdp "+pdp);
760                                 }
761                         }
762                         //add possible policies to group (filesystem only, apparently)
763                 } else {
764                         if(!(localGroup instanceof StdPDPGroup)){
765                                 throw new PAPException("group is not a StdPDPGroup");
766                         }
767                         //clone the object
768                         //because it will be comparing the new group to its own version
769                         StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(),localGroup.isDefaultGroup(),localGroup.getName(),localGroup.getDescription(),((StdPDPGroup)localGroup).getDirectory());
770                         localGroupClone.setEcompPdps(localGroup.getEcompPdps());
771                         localGroupClone.setPipConfigs(localGroup.getPipConfigs());
772                         localGroupClone.setStatus(localGroup.getStatus());                      
773                         //we are updating a group or adding a policy or changing default
774                         //set default if it should be
775                         if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){
776                                 try {
777                                         papEngine.SetDefaultGroup(localGroup);
778                                         return;
779                                 } catch (PAPException e) {
780                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");");
781                                         throw new PAPException("Could not set default group to "+localGroupClone);
782                                 }                               
783                         }               
784                         boolean needToUpdate = false;
785                         if(updateGroupPoliciesInFileSystem(localGroupClone,localGroup, groupRecord, transaction)){
786                                 needToUpdate = true;
787                         }
788                         if(!stringEquals(localGroupClone.getId(),groupRecord.getGroupId()) || !stringEquals(localGroupClone.getName(),groupRecord.getgroupName())){
789                                 //changing ids
790                                 //we do not want to change the id, the papEngine will do this for us, it needs to know the old id
791                                 localGroupClone.setName(groupRecord.getgroupName());
792                                 needToUpdate = true;
793                         }
794                         if(!stringEquals(localGroupClone.getDescription(),groupRecord.getDescription())){
795                                 localGroupClone.setDescription(groupRecord.getDescription());
796                                 needToUpdate = true;
797                         }
798                         if(needToUpdate){
799                                 try {
800
801                                         papEngine.updateGroup(localGroupClone);
802                                 } catch (PAPException e) {
803                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");");
804                                         throw new PAPException("Could not update group "+localGroupClone);
805                                 }
806                         }                               
807
808                 }
809                 //call command that corresponds to the change that was made
810         }
811         //this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db
812         private boolean updateGroupPoliciesInFileSystem(EcompPDPGroup pdpGroup,EcompPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException{
813                 if(!(pdpGroup instanceof StdPDPGroup)){
814                         throw new PAPException("group is not a StdPDPGroup");
815                 }
816                 StdPDPGroup group = (StdPDPGroup)pdpGroup;
817                 //this must always be true since we don't explicitly know when a delete is occuring
818                 boolean didUpdate = true;
819                 HashMap<String,PDPPolicy> currentPolicySet = new HashMap<String,PDPPolicy>(oldPdpGroup.getPolicies().size());
820                 HashSet<PDPPolicy> newPolicySet = new HashSet<>();
821                 for(PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()){
822                         currentPolicySet.put(pdpPolicy.getId(), pdpPolicy);
823                 }
824                 for(PolicyEntity policy : groupRecord.getPolicies()){
825                         String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
826                         if(group.getPolicy(pdpPolicyName) == null){
827                                 didUpdate = true;
828                                 if(currentPolicySet.containsKey(pdpPolicyName)){
829                                         newPolicySet.add(currentPolicySet.get(pdpPolicyName));
830                                 } else{
831                                         InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
832                                         group.copyPolicyToFile(pdpPolicyName,policyStream);
833                                         ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(policy.getPolicyName()));
834                                         try {
835                                                 policyStream.close();
836                                         } catch (IOException e) {
837                                                 didUpdate = false;
838                                                 PolicyLogger.error(e.getMessage() +e);
839                                         }
840                                 }
841                         }
842                 }
843                 if(didUpdate){
844                         newPolicySet.addAll(group.getPolicies());
845                         group.setPolicies(newPolicySet);
846                 }
847                 return didUpdate;
848
849         }
850         private String removeExtensionAndVersionFromPolicyName(String originalPolicyName){
851         return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0];
852     }
853
854     /**
855      * Splits apart the policy name and version from a policy file path
856      * @param originalPolicyName: a policy file name ex: Config_policy.2.xml
857      * @return An array [0]: The policy name, [1]: the policy version, as a string
858      */
859     private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){
860         String policyName = originalPolicyName;
861         String[] nameAndVersion = new String[2];
862         try{
863             policyName = removeFileExtension(policyName);
864             nameAndVersion[0] = policyName.substring(0,policyName.lastIndexOf('.'));
865             if(isNullOrEmpty(nameAndVersion[0])){
866                 throw new Exception();
867             }
868         } catch(Exception e){
869             nameAndVersion[0] = originalPolicyName;         
870         }
871         try{
872             nameAndVersion[1] = policyName.substring(policyName.lastIndexOf('.')+1);
873             if(isNullOrEmpty(nameAndVersion[1])){
874                 throw new Exception();
875             }
876         } catch(Exception e){
877             nameAndVersion[1] = "1";
878         }
879         return nameAndVersion;
880     }
881     
882         private void handleIncomingPdpChange(String url, String pdpId, PolicyDBDaoTransaction transaction) throws PAPException{
883                 //get pdp
884                 long pdpIdLong = -1;
885                 try{
886                         pdpIdLong = Long.parseLong(pdpId);
887                 }catch(NumberFormatException e){
888                         throw new IllegalArgumentException("pdpId "+pdpId+" cannot be parsed into a long");
889                 }
890                 PdpEntity pdpRecord = null;
891                 try{
892                         pdpRecord = transaction.getPdp(pdpIdLong);
893                 }catch(Exception e){
894                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");");
895                         throw new PAPException("Could not get local pdp "+pdpIdLong);
896                 }
897                 if(pdpRecord == null){
898                         throw new PersistenceException("The pdpRecord returned is null");
899                 }
900                 PDP localPdp = null;
901                 try {
902                         localPdp = papEngine.getPDP(pdpRecord.getPdpId());
903                 } catch (PAPException e) {
904                         logger.warn("Caught PAPException trying to get local pdp  with papEngine.getPDP("+pdpId+");",e);
905                 }
906                 if(localPdp != null && pdpRecord.isDeleted()){
907                         try {
908                                 papEngine.removePDP((EcompPDP) localPdp);
909                         } catch (PAPException e) {
910                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");");
911                                 throw new PAPException("Could not remove pdp "+pdpId);
912                         }
913                 }
914                 else if(localPdp == null){
915                         //add new pdp
916                         //get group
917                         EcompPDPGroup localGroup = null;
918                         try {
919                                 localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
920                         } catch (PAPException e1) {
921                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
922                                 throw new PAPException("Could not get local group");
923                         }                       
924                         try {
925                                 papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort());
926                         } catch (NullPointerException | PAPException e) {
927                                 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()+");");
928                                 throw new PAPException("Could not create pdp "+pdpRecord);
929                         }
930                 } else {
931                         boolean needToUpdate = false;
932                         if(!stringEquals(localPdp.getId(),pdpRecord.getPdpId()) || !stringEquals(localPdp.getName(),pdpRecord.getPdpName())){
933                                 //again, we don't want to change the id, the papEngine will do this
934                                 localPdp.setName(pdpRecord.getPdpName());
935                                 needToUpdate = true;
936                         }
937                         if(!stringEquals(localPdp.getDescription(),pdpRecord.getDescription())){
938                                 localPdp.setDescription(pdpRecord.getDescription());
939                                 needToUpdate = true;
940                         }
941                         String localPdpGroupId = null;
942                         try{
943                                 localPdpGroupId = papEngine.getPDPGroup((EcompPDP) localPdp).getId();
944                         } catch(PAPException e){
945                                 //could be null or something, just warn at this point
946                                 logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();",e);
947                         }
948                         if(!stringEquals(localPdpGroupId,pdpRecord.getGroup().getGroupId())){
949                                 EcompPDPGroup newPdpGroup = null;
950                                 try{
951                                         newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
952                                 }catch(PAPException e){
953                                         //ok, now we have an issue. Time to stop things
954                                         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());");
955                                         throw new PAPException("Could not get local group");
956                                 }
957                                 try{
958                                         papEngine.movePDP((EcompPDP) localPdp, newPdpGroup);
959                                 }catch(PAPException e){
960                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);");
961                                         throw new PAPException("Could not move pdp "+localPdp);
962                                 }
963                         }
964                         if(((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()){
965                                 ((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort());
966                                 needToUpdate = true;
967                         }
968                         if(needToUpdate){
969                                 try {
970                                         papEngine.updatePDP((EcompPDP) localPdp);
971                                 } catch (PAPException e) {
972                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");");
973                                         throw new PAPException("Could not update pdp "+localPdp);
974                                 }
975                         }
976                 }
977                 //compare to local situation
978                 //call command to update
979         }
980         private void handleIncomingPolicyChange(String url, String policyId,String oldPathString){
981                 EntityManager em = emf.createEntityManager();
982                 Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById");
983                 getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId));
984
985                 @SuppressWarnings("unchecked")
986                 List<PolicyEntity> policies = getPolicyEntityQuery.getResultList();
987                 PolicyEntity policy = null;
988                 if (!policies.isEmpty()){
989                         policy = policies.get(0);
990                 }
991                 String action = "unknown action";
992                 try {
993                         if(policy != null){
994                                 logger.debug("Deleting Policy: " + policy.getPolicyName());
995                                 action = "delete";
996                                 Path subFile = null;
997
998                                 if (policy.getConfigurationData()!= null){
999                                         subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), "Config");
1000                                 }else if(policy.getActionBodyEntity()!= null){
1001                                         subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), "Action");
1002                                 }
1003
1004                                 if(subFile != null){
1005                                         Files.deleteIfExists(subFile);
1006                                 }
1007                                 if (policy.getConfigurationData()!= null){
1008                                         writePolicySubFile(policy, "Config");
1009                                 }else if(policy.getActionBodyEntity()!= null){
1010                                         writePolicySubFile(policy, "Action");
1011                                 }
1012                         }
1013                 } catch (IOException e1) {
1014                         String policyName = policy.getPolicyName();
1015                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while performing [" + action + "] of Policy File: " + policyName);
1016                 }       
1017         }
1018
1019         private String getPdpPolicyName(String name, String scope){
1020                 String finalName = "";
1021                 finalName += scope;
1022                 finalName += ".";
1023                 finalName += removeFileExtension(name);
1024                 finalName += ".xml";
1025                 return finalName;
1026         }
1027         private String removeFileExtension(String fileName){
1028                 return fileName.substring(0, fileName.lastIndexOf('.'));
1029         }
1030
1031         private Path getPolicySubFile(String filename, String subFileType){
1032                 logger.debug("getPolicySubFile(" + filename + ", " + subFileType + ")");
1033                 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), subFileType);
1034                 File file = null;
1035
1036                 filename = FilenameUtils.removeExtension(filename);
1037
1038                 for(File tmpFile : filePath.toFile().listFiles()){
1039                         if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)){
1040                                 file = tmpFile;
1041                         }
1042                 }
1043
1044                 Path finalPath = null;
1045                 if (file!= null){
1046                         finalPath = Paths.get(file.getAbsolutePath());
1047                 }
1048
1049                 logger.debug("end of getPolicySubFile: " + finalPath);
1050                 return finalPath;       
1051         }
1052
1053         private boolean writePolicySubFile(PolicyEntity policy, String policyType){
1054                 logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + "]");
1055                 String type = null;
1056                 String subTypeName = null;
1057                 String subTypeBody = null;
1058                 if (policyType.equalsIgnoreCase("config")){
1059                         type = "Config";
1060                         subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName());
1061                         subTypeBody = policy.getConfigurationData().getConfigBody();
1062
1063                         String configType = policy.getConfigurationData().getConfigType();
1064
1065
1066                         if (configType != null) {
1067                                 if (configType.equals(JSON_CONFIG)) {
1068                                         subTypeName = subTypeName + ".json";
1069                                 }
1070                                 if (configType.equals(XML_CONFIG)) {
1071                                         subTypeName = subTypeName + ".xml";
1072                                 }
1073                                 if (configType.equals(PROPERTIES_CONFIG)) {
1074                                         subTypeName = subTypeName + ".properties";
1075                                 }
1076                                 if (configType.equals(OTHER_CONFIG)) {
1077                                         subTypeName = subTypeName + ".txt";
1078                                 }
1079                         }
1080
1081                 }else if (policyType.equalsIgnoreCase("action")){
1082                         type = "Action";
1083                         subTypeName = policy.getActionBodyEntity().getActionBodyName();
1084                         subTypeBody = policy.getActionBodyEntity().getActionBody();
1085
1086
1087                 }
1088                 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type);
1089
1090                 if(subTypeBody == null){
1091                         subTypeBody = "";
1092                 }
1093                 boolean success = false;
1094                 try {
1095                         Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName));
1096                         File file = Paths.get(filePath.toString(),subTypeName).toFile();
1097                         file.createNewFile();
1098                         FileWriter fileWriter = new FileWriter(file, false); // false to overwrite
1099                         fileWriter.write(subTypeBody);
1100                         fileWriter.close();
1101                         success = true;
1102
1103                 } catch (Exception e) {
1104                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName());
1105                 }                                       
1106
1107                 return success;
1108
1109         }
1110
1111         public void auditLocalDatabase(PAPPolicyEngine papEngine2){
1112                 logger.debug("PolicyDBDao.auditLocalDatabase() is called");
1113                 try{
1114                         deleteAllGroupTables();
1115                         auditGroups(papEngine2);
1116                 } catch(Exception e){
1117                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "auditLocalDatabase() error");
1118                         logger.error("Exception Occured"+e);
1119                 }
1120         }
1121
1122         public void deleteAllGroupTables(){
1123                 logger.debug("PolicyDBDao.deleteAllGroupTables() called");
1124                 EntityManager em = emf.createEntityManager();
1125                 em.getTransaction().begin();
1126
1127                 Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll");
1128                 deletePdpEntityEntityTableUpdate.executeUpdate();
1129
1130                 Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll");
1131                 deleteGroupEntityTableUpdate.executeUpdate();
1132
1133                 em.getTransaction().commit();
1134                 em.close();
1135         }
1136
1137         @SuppressWarnings("unchecked")
1138         public void auditGroups(PAPPolicyEngine papEngine2){
1139                 logger.debug("PolicyDBDao.auditGroups() called");
1140
1141                 EntityManager em = emf.createEntityManager();
1142                 em.getTransaction().begin();
1143                 final String AUDIT_STR = "Audit";
1144                 try{
1145
1146                         Set<EcompPDPGroup> groups = papEngine2.getEcompPDPGroups();
1147
1148                         for (EcompPDPGroup grp : groups){
1149                                 try{
1150                                         GroupEntity groupEntity = new GroupEntity();
1151                                         em.persist(groupEntity);
1152                                         groupEntity.setGroupName(grp.getName());
1153                                         groupEntity.setDescription(grp.getDescription());
1154                                         groupEntity.setDefaultGroup(grp.isDefaultGroup());
1155                                         groupEntity.setCreatedBy(AUDIT_STR);
1156                                         groupEntity.setGroupId(createNewPDPGroupId(grp.getId()));
1157                                         groupEntity.setModifiedBy(AUDIT_STR);
1158                                         Set<EcompPDP> pdps =  grp.getEcompPdps();                               
1159
1160                                         for(EcompPDP pdp : pdps){
1161                                                 PdpEntity pdpEntity = new PdpEntity();
1162                                                 em.persist(pdpEntity);
1163                                                 pdpEntity.setGroup(groupEntity);
1164                                                 pdpEntity.setJmxPort(pdp.getJmxPort());
1165                                                 pdpEntity.setPdpId(pdp.getId());
1166                                                 pdpEntity.setPdpName(pdp.getName());
1167                                                 pdpEntity.setModifiedBy(AUDIT_STR);
1168                                                 pdpEntity.setCreatedBy(AUDIT_STR);
1169
1170                                         }
1171
1172                                         Set<PDPPolicy> policies = grp.getPolicies();
1173
1174                                         for(PDPPolicy policy : policies){
1175                                                 try{
1176                                                         String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId());
1177                                                         List<PolicyEntity> policyEntityList;
1178                                                         Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope");
1179                                                         getPolicyEntitiesQuery.setParameter("name", stringArray[0]);
1180                                                         getPolicyEntitiesQuery.setParameter("scope", stringArray[1]);
1181
1182                                                         policyEntityList = getPolicyEntitiesQuery.getResultList();
1183                                                         PolicyEntity policyEntity = null;
1184                                                         if(!policyEntityList.isEmpty()){
1185                                                                 policyEntity = policyEntityList.get(0);
1186                                                         }
1187                                                         if(policyEntity != null){
1188                                                                 groupEntity.addPolicyToGroup(policyEntity);
1189                                                         }
1190                                                 }catch(Exception e2){
1191                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Exception auditGroups inner catch");
1192                                                 }
1193                                         }
1194                                 }catch(Exception e1){
1195                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Exception auditGroups middle catch");
1196                                 }
1197                         }
1198                 }catch(Exception e){
1199                         em.getTransaction().rollback();
1200                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception auditGroups outer catch");
1201                         em.close();
1202                         return;
1203                 }
1204
1205                 em.getTransaction().commit();
1206                 em.close();
1207
1208         }
1209
1210         private String getConfigFile(String filename, PolicyRestAdapter policy){
1211                 if(policy == null){
1212                         return getConfigFile(filename, (String)null);
1213                 }
1214                 return getConfigFile(filename, policy.getConfigType());
1215         }
1216         //copied from ConfigPolicy.java and modified
1217         // Here we are adding the extension for the configurations file based on the
1218         // config type selection for saving.
1219         private String getConfigFile(String filename, String configType) {
1220                 logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile("+filename+", "+configType+") called");
1221                 filename = FilenameUtils.removeExtension(filename);
1222                 String id = configType;
1223
1224                 if (id != null) {
1225                         if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) {
1226                                 filename = filename + ".json";
1227                         }
1228                         if (id.equals(ConfigPolicy.XML_CONFIG)) {
1229                                 filename = filename + ".xml";
1230                         }
1231                         if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) {
1232                                 filename = filename + ".properties";
1233                         }
1234                         if (id.equals(ConfigPolicy.OTHER_CONFIG)) {
1235                                 filename = filename + ".txt";
1236                         }
1237                 }
1238                 return filename;
1239         }
1240         
1241         private String[] getNameScopeAndVersionFromPdpPolicy(String fileName){
1242                 String[] splitByDots = fileName.split("\\.");
1243                 if(splitByDots.length < 3){
1244                         //should we throw something
1245                         return null;
1246                 }
1247                 String policyName = splitByDots[splitByDots.length-3];
1248                 String version = splitByDots[splitByDots.length-2];
1249                 //policy names now include version
1250                 String scope = "";
1251                 for(int i=0;i<splitByDots.length-3;i++){
1252                         scope += ".".concat(splitByDots[i]);
1253                 }
1254                 //remove the first dot
1255                 if(scope.length() > 0){
1256                         scope = scope.substring(1);
1257                 }
1258                 String[] returnArray = new String[3];
1259                 returnArray[0] = policyName + "." + version + ".xml";
1260                 returnArray[2] = version;
1261                 returnArray[1] = scope;
1262                 return returnArray;
1263         }
1264
1265         //copied from StdEngine.java
1266         public static String createNewPDPGroupId(String name) {
1267                 String id = name;
1268                 // replace "bad" characters with sequences that will be ok for file names and properties keys.
1269                 id = id.replace(" ", "_sp_");
1270                 id = id.replace("\t", "_tab_");
1271                 id = id.replace("\\", "_bksl_");
1272                 id = id.replace("/", "_sl_");
1273                 id = id.replace(":", "_col_");
1274                 id = id.replace("*", "_ast_");
1275                 id = id.replace("?", "_q_");
1276                 id = id.replace("\"", "_quo_");
1277                 id = id.replace("<", "_lt_");
1278                 id = id.replace(">", "_gt_");
1279                 id = id.replace("|", "_bar_");
1280                 id = id.replace("=", "_eq_");
1281                 id = id.replace(",", "_com_");
1282                 id = id.replace(";", "_scom_");
1283
1284                 return id;
1285         }
1286
1287         /**
1288          * Checks if any of the given strings are empty or null
1289          * @param strings One or more Strings (or nulls) to check if they are null or empty
1290          * @return true if one or more of the given strings are empty or null
1291          */
1292         private static boolean isNullOrEmpty(String... strings){
1293                 for(String s : strings){
1294                         if(!(s instanceof String)){
1295                                 return true;
1296                         }
1297                         if(s.equals("")){
1298                                 return true;
1299                         }
1300                 }
1301                 return false;
1302         }
1303
1304         
1305         private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction {
1306                 private EntityManager em;
1307                 private final Object emLock = new Object();
1308                 long policyId;
1309                 long groupId;
1310                 long pdpId;
1311                 String newGroupId;
1312                 private boolean operationRun = false;
1313                 private final Thread transactionTimer;
1314
1315                 private PolicyDBDaoTransactionInstance(){
1316                         //call the constructor with arguments
1317                         this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)),
1318                                         Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)));
1319                 }
1320                 //timeout is how long the transaction can sit before rolling back
1321                 //wait time is how long to wait for the transaction to start before throwing an exception
1322                 private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime){
1323                         if(logger.isDebugEnabled()){
1324                                 logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:"
1325                                                 + "\n   transactionTimeout = " + transactionTimeout
1326                                                 + "\n   transactionWaitTime = " + transactionWaitTime + "\n\n");
1327                         }
1328                         this.em = emf.createEntityManager();
1329                         policyId = -1;
1330                         groupId = -1;
1331                         pdpId = -1;
1332                         newGroupId = null;
1333                         synchronized(emLock){
1334                                 try{
1335                                         startTransactionSynced(this.em,transactionWaitTime);
1336                                 } catch(Exception e){
1337                                         throw new PersistenceException("Could not lock transaction within "+transactionWaitTime+" milliseconds");
1338                                 }
1339                         }
1340                         class TransactionTimer implements Runnable {
1341
1342                                 private int sleepTime;
1343                                 public TransactionTimer(int timeout){
1344                                         this.sleepTime = timeout;
1345                                 }
1346                                 @Override
1347                                 public void run() {
1348                                         if(logger.isDebugEnabled()){
1349                                                 Date date= new java.util.Date();
1350                                                 logger.debug("\n\nTransactionTimer.run() - SLEEPING: "
1351                                                                 + "\n   sleepTime (ms) = " + sleepTime 
1352                                                                 + "\n   TimeStamp = " + date.getTime()
1353                                                                 + "\n\n");
1354                                         }
1355                                         try {
1356                                                 Thread.sleep(sleepTime);
1357                                         } catch (InterruptedException e) {
1358                                                 //probably, the transaction was completed, the last thing we want to do is roll back
1359                                                 if(logger.isDebugEnabled()){
1360                                                         Date date= new java.util.Date();
1361                                                         logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: "
1362                                                                         + "\n   TimeStamp = " + date.getTime()
1363                                                                         + "\n\n");
1364                                                 }
1365                                                 return;
1366                                         }
1367                                         if(logger.isDebugEnabled()){
1368                                                 Date date= new java.util.Date();
1369                                                 logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: "
1370                                                                 + "\n   TimeStamp = " + date.getTime()
1371                                                                 + "\n\n");
1372                                         }
1373                                         rollbackTransaction();                                  
1374                                 }
1375
1376                         }
1377
1378                         transactionTimer = new Thread(new TransactionTimer(transactionTimeout),"transactionTimerThread");
1379                         transactionTimer.start();
1380
1381
1382                 }
1383
1384                 private void checkBeforeOperationRun(){
1385                         checkBeforeOperationRun(false);
1386                 }
1387                 private void checkBeforeOperationRun(boolean justCheckOpen){
1388                         if(!isTransactionOpen()){
1389                                 PolicyLogger.error("There is no transaction currently open");
1390                                 throw new IllegalStateException("There is no transaction currently open");
1391                         }
1392                         if(operationRun && !justCheckOpen){
1393                                 PolicyLogger.error("An operation has already been performed and the current transaction should be committed");
1394                                 throw new IllegalStateException("An operation has already been performed and the current transaction should be committed");
1395                         }
1396                         operationRun = true;
1397                 }
1398                 @Override
1399                 public void commitTransaction() {
1400                         synchronized(emLock){
1401                                 logger.debug("commitTransaction() as commitTransaction() called");
1402                                 if(!isTransactionOpen()){
1403                                         logger.warn("There is no open transaction to commit");
1404                                         try{
1405                                                 em.close();
1406                                         } catch(Exception e){
1407                                                 logger.error("Exception Occured"+e);
1408                                         }
1409                                         return;
1410                                 }
1411                                 try{
1412                                         em.getTransaction().commit();
1413                                 } catch(RollbackException e){
1414                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught RollbackException on em.getTransaction().commit()");
1415                                         throw new PersistenceException("The commit failed. Message:\n"+e.getMessage());
1416                                 }
1417                                 em.close();
1418                                 // need to revisit
1419                                 if(policyId >= 0){
1420                                         if(newGroupId != null){
1421                                                 try{
1422                                                         notifyOthers(policyId,POLICY_NOTIFICATION,newGroupId);
1423                                                 } catch(Exception e){
1424                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")");
1425                                                 }
1426                                         } else {
1427                                                 try{
1428                                                         notifyOthers(policyId,POLICY_NOTIFICATION);
1429                                                 } catch(Exception e){
1430                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")");
1431                                                 }
1432                                         }
1433                                 }
1434                                 if(groupId >= 0){
1435                                         //we don't want commit to fail just because this does
1436                                         if(newGroupId != null){
1437                                                 try{
1438                                                         notifyOthers(groupId,GROUP_NOTIFICATION,newGroupId);
1439                                                 } catch(Exception e){
1440                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")");
1441                                                 }
1442                                         } else {
1443                                                 try{
1444                                                         notifyOthers(groupId,GROUP_NOTIFICATION);
1445                                                 } catch(Exception e){
1446                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")");
1447                                                 }
1448                                         }
1449                                 }
1450                                 if(pdpId >= 0){
1451                                         //we don't want commit to fail just because this does
1452                                         try{
1453                                                 notifyOthers(pdpId,PDP_NOTIFICATION);
1454                                         } catch(Exception e){
1455                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")");
1456                                         }
1457                                 }
1458                         }
1459                         if(transactionTimer instanceof Thread){
1460                                 transactionTimer.interrupt();
1461                         }
1462                 }
1463
1464                 @Override
1465                 public void rollbackTransaction() {
1466                         logger.debug("rollbackTransaction() as rollbackTransaction() called");
1467                         synchronized(emLock){
1468                                 if(isTransactionOpen()){        
1469
1470                                         try{
1471                                                 em.getTransaction().rollback();                                 
1472                                         } catch(Exception e){
1473                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not rollback transaction");
1474                                         }
1475                                         try{
1476                                                 em.close();
1477                                         }catch(Exception e){
1478                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not close EntityManager");
1479                                         }
1480
1481                                 } else {
1482                                         try{
1483                                                 em.close();
1484                                         }catch(Exception e){
1485                                                 logger.warn("Could not close already closed transaction");
1486                                         }
1487                                 }
1488
1489                         }
1490                         if(transactionTimer instanceof Thread){
1491                                 transactionTimer.interrupt();
1492                         }
1493
1494
1495                 }
1496
1497                 private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) {
1498                         logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) as createPolicy("+policy+", "+username+", "+policyScope+", "+policyName+", "+policyDataString+") called");
1499                         synchronized(emLock){
1500                                 checkBeforeOperationRun();
1501                                 String configName = policyName;
1502                                 if(policyName.contains("Config_")){
1503                                         policyName = policyName.replace(".Config_", ":Config_");
1504                                 }else if(policyName.contains("Action_")){
1505                                         policyName = policyName.replace(".Action_", ":Action_");
1506                                 }else if(policyName.contains("Decision_")){
1507                                         policyName = policyName.replace(".Decision_", ":Decision_");
1508                                 }
1509                                 policyName = policyName.split(":")[1];
1510                                 Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName");                     
1511                                 createPolicyQuery.setParameter("scope", policyScope);
1512                                 createPolicyQuery.setParameter("policyName", policyName);
1513                                 List<?> createPolicyQueryList = createPolicyQuery.getResultList();
1514                                 PolicyEntity newPolicyEntity;
1515                                 boolean update;
1516                                 if(createPolicyQueryList.size() < 1){
1517                                         newPolicyEntity = new PolicyEntity();
1518                                         update = false;
1519                                 } else if(createPolicyQueryList.size() > 1){
1520                                         PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1521                                         throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1522                                 } else {
1523                                         newPolicyEntity = (PolicyEntity)createPolicyQueryList.get(0);
1524                                         update = true;
1525                                 }                       
1526
1527                                 ActionBodyEntity newActionBodyEntity = null;
1528                                 if(policy.getPolicyType().equals("Action")){
1529                                         boolean abupdate = false;
1530                                         if(newPolicyEntity.getActionBodyEntity() == null){
1531                                                 newActionBodyEntity = new ActionBodyEntity();
1532                                         }else{
1533                                                 newActionBodyEntity = em.find(ActionBodyEntity.class, newPolicyEntity.getActionBodyEntity().getActionBodyId());
1534                                                 abupdate = true;
1535                                         }
1536
1537                                         if(newActionBodyEntity != null){
1538                                                 if(!abupdate){
1539                                                         em.persist(newActionBodyEntity);
1540                                                 }
1541                                                 //build the file path
1542                                                 //trim the .xml off the end
1543                                                 String policyNameClean = FilenameUtils.removeExtension(configName);
1544                                                 String actionBodyName =  policyNameClean + ".json";
1545                                                 Path actionBodyPath = Paths.get(Webapps.getActionHome(), actionBodyName);
1546                                                 if(logger.isDebugEnabled()){
1547                                                         logger.debug("\nPolicyDBDao.createPolicy"
1548                                                                         + "\n   actionBodyPath = " + actionBodyPath);
1549                                                 }
1550                                                 //get the action body
1551                                                 String actionBodyString = null;
1552                                                 String actionBodyPathStr = null;
1553                                                 InputStream fileContentStream = null;
1554
1555                                                 if (Files.exists(actionBodyPath)) {
1556                                                         try {
1557                                                                 actionBodyPathStr = (actionBodyPath != null ? actionBodyPath.toString() : null);
1558                                                                 fileContentStream = new FileInputStream(actionBodyPathStr);
1559                                                                 actionBodyString = IOUtils.toString(fileContentStream);
1560                                                                 if(logger.isDebugEnabled()){
1561                                                                         logger.debug("\nPolicyDBDao.createPolicy"
1562                                                                                         + "\n   actionBodyPathStr = " + actionBodyPathStr
1563                                                                                         + "\n   actionBodyString = " + actionBodyString);
1564                                                                 }
1565                                                         } catch (FileNotFoundException e) {
1566                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")");
1567                                                                 throw new IllegalArgumentException("The actionBodyPathStr file path " + actionBodyPathStr + " does not exist" 
1568                                                                                 + "\nEXCEPTION: " + e);
1569                                                         } catch(IOException e2){
1570                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")");
1571                                                                 throw new IllegalArgumentException("The actionBodyPath file path cannot be read" + fileContentStream 
1572                                                                                 + "\nEXCEPTION: " + e2);
1573                                                         } finally {
1574                                                                 IOUtils.closeQuietly(fileContentStream);
1575                                                         }
1576
1577                                                         if(actionBodyString == null){
1578                                                                 throw new IllegalArgumentException("The file path (" + actionBodyPathStr + ") cannot be read");
1579                                                         }
1580                                                 } else {
1581                                                         actionBodyString = "{}";
1582                                                 }
1583
1584                                                 newActionBodyEntity.setActionBody(actionBodyString);
1585                                                 newActionBodyEntity.setActionBodyName(actionBodyName);
1586                                                 newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()");
1587                                                 newActionBodyEntity.setDeleted(false);
1588                                                 if(!abupdate){
1589                                                         newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()");
1590                                                 }
1591                                                 if(logger.isDebugEnabled()){
1592                                                         logger.debug("\nPolicyDBDao.createPolicy"
1593                                                                         + "\n   newActionBodyEntity.getActionBody() = " + newActionBodyEntity.getActionBody()
1594                                                                         + "\n   newActionBodyEntity.getActionBodyName() = " + newActionBodyEntity.getActionBodyName()
1595                                                                         + "\n   newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy()
1596                                                                         + "\n   newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy()
1597                                                                         + "\n   newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted()
1598                                                                         + "\n   FLUSHING to DB");
1599                                                 }
1600                                                 //push the actionBodyEntity to the DB
1601                                                 em.flush();
1602                                         }else{
1603                                                 //newActionBodyEntity == null
1604                                                 //We have a actionBody in the policy but we found no actionBody in the DB
1605                                                 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an "
1606                                                                 + "actionBody, but it could not be found in the DB for update."
1607                                                                 + "\n  policyScope = " + policyScope
1608                                                                 + "\n  policyName = " + policyName + "\n\n";
1609                                                 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it could not be found in the DB for update: policyName = " + policyName);
1610                                                 throw new IllegalArgumentException(msg);
1611                                         }
1612                                 }
1613
1614                                 ConfigurationDataEntity newConfigurationDataEntity;
1615                                 if(policy.getPolicyType().equals("Config")){
1616                                         boolean configUpdate;
1617                                         if(newPolicyEntity.getConfigurationData() == null){
1618                                                 newConfigurationDataEntity = new ConfigurationDataEntity();
1619                                                 configUpdate = false;
1620                                         } else {
1621                                                 newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, newPolicyEntity.getConfigurationData().getConfigurationDataId());
1622                                                 configUpdate = true;
1623                                         }
1624
1625                                         if(newConfigurationDataEntity != null){
1626                                                 if(!configUpdate){
1627                                                         em.persist(newConfigurationDataEntity);
1628                                                 }
1629                                                 if(!stringEquals(newConfigurationDataEntity.getConfigurationName(),getConfigFile(configName,policy))){
1630                                                         newConfigurationDataEntity.setConfigurationName(getConfigFile(configName,policy));
1631                                                 }
1632                                                 if(newConfigurationDataEntity.getConfigType() == null || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())){
1633                                                         newConfigurationDataEntity.setConfigType(policy.getConfigType());
1634                                                 }
1635                                                 if(!configUpdate){
1636                                                         newConfigurationDataEntity.setCreatedBy(username);
1637                                                 }
1638                                                 if(newConfigurationDataEntity.getModifiedBy() == null || !newConfigurationDataEntity.getModifiedBy().equals(username)){
1639                                                         newConfigurationDataEntity.setModifiedBy(username);
1640                                                 }                                       
1641                                                 if(newConfigurationDataEntity.getDescription() == null || !newConfigurationDataEntity.getDescription().equals("")){
1642                                                         newConfigurationDataEntity.setDescription("");
1643                                                 }
1644                                                 if(newConfigurationDataEntity.getConfigBody() == null || newConfigurationDataEntity.getConfigBody().isEmpty() ||
1645                                                                 (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))){
1646                                                         //hopefully one of these won't be null
1647                                                         if(policy.getConfigBodyData() == null || policy.getConfigBodyData().isEmpty()){
1648                                                                 newConfigurationDataEntity.setConfigBody(policy.getJsonBody());
1649                                                         }else{
1650                                                                 newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData());
1651                                                         }
1652                                                 }
1653                                                 if(newConfigurationDataEntity.isDeleted() == true){
1654                                                         newConfigurationDataEntity.setDeleted(false);
1655                                                 }
1656
1657                                                 em.flush();
1658                                         }else{
1659                                                 //We have a configurationData body in the policy but we found no configurationData body in the DB
1660                                                 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a "
1661                                                                 + "configurationData body, but it could not be found in the DB for update."
1662                                                                 + "\n  policyScope = " + policyScope
1663                                                                 + "\n  policyName = " + policyName + "\n\n";
1664                                                 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, but it could not be found in the DB for update: policyName = " + policyName);
1665                                                 throw new IllegalArgumentException(msg);
1666                                         }
1667
1668                                 } else {
1669                                         newConfigurationDataEntity = null;
1670                                 }
1671                                 if(!update){
1672                                         em.persist(newPolicyEntity);
1673                                 }
1674
1675                                 policyId = newPolicyEntity.getPolicyId();
1676
1677                                 if(!stringEquals(newPolicyEntity.getPolicyName(),policyName)){
1678                                         newPolicyEntity.setPolicyName(policyName);
1679                                 }
1680                                 if(!stringEquals(newPolicyEntity.getCreatedBy(),username)){
1681                                         newPolicyEntity.setCreatedBy(username);
1682                                 }
1683                                 if(!stringEquals(newPolicyEntity.getDescription(),policy.getPolicyDescription())){
1684                                         newPolicyEntity.setDescription(policy.getPolicyDescription());
1685                                 }
1686                                 if(!stringEquals(newPolicyEntity.getModifiedBy(),username)){
1687                                         newPolicyEntity.setModifiedBy(username);
1688                                 }
1689                                 if(!stringEquals(newPolicyEntity.getPolicyData(),policyDataString)){
1690                                         newPolicyEntity.setPolicyData(policyDataString);
1691                                 }
1692                                 if(!stringEquals(newPolicyEntity.getScope(),policyScope)){
1693                                         newPolicyEntity.setScope(policyScope);
1694                                 }
1695                                 if(newPolicyEntity.isDeleted() == true){
1696                                         newPolicyEntity.setDeleted(false);
1697                                 }
1698                                 newPolicyEntity.setConfigurationData(newConfigurationDataEntity);
1699                                 newPolicyEntity.setActionBodyEntity(newActionBodyEntity);
1700
1701
1702                                 em.flush();
1703                                 this.policyId = newPolicyEntity.getPolicyId();
1704                         }
1705
1706                         return;
1707                 }
1708
1709                 @SuppressWarnings("unused")
1710                 public PolicyEntity getPolicy(int policyID){
1711                         return getPolicy(policyID,null,null);
1712                 }
1713                 public PolicyEntity getPolicy(String policyName,String scope){
1714                         return getPolicy(-1,policyName,scope);
1715                 }
1716                 private PolicyEntity getPolicy(int policyID, String policyName,String scope){
1717                         logger.debug("getPolicy(int policyId, String policyName) as getPolicy("+policyID+","+policyName+") called");
1718                         if(policyID < 0 && isNullOrEmpty(policyName,scope)){
1719                                 throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank");
1720                         }
1721
1722                         synchronized(emLock){
1723                                 checkBeforeOperationRun(true);
1724                                 //check if group exists
1725                                 String policyId;
1726                                 Query policyQuery;
1727                                 if(!isNullOrEmpty(policyName,scope)){
1728                                         policyId = policyName;
1729                                         policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope");
1730                                         policyQuery.setParameter("name", policyId);
1731                                         policyQuery.setParameter("scope", scope);
1732                                 } else{
1733                                         policyId = String.valueOf(policyID);
1734                                         policyQuery = em.createNamedQuery("PolicyEntity.FindById");
1735                                         policyQuery.setParameter("id", policyId);
1736                                 }
1737                                 List<?> policyQueryList;
1738                                 try{
1739                                         policyQueryList = policyQuery.getResultList();
1740                                 }catch(Exception e){
1741                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get policy with policyQuery.getResultList()");
1742                                         throw new PersistenceException("Query failed trying to get policy "+policyId);
1743                                 }
1744                                 if(policyQueryList.size() < 1){
1745                                         PolicyLogger.error("Policy does not exist with id "+policyId);
1746                                         throw new PersistenceException("Group policy is being added to does not exist with id "+policyId);
1747                                 } else if(policyQueryList.size() > 1){
1748                                         PolicyLogger.error("Somehow, more than one policy with the id "+policyId+" were found in the database");
1749                                         throw new PersistenceException("Somehow, more than one policy with the id "+policyId+" were found in the database");
1750                                 }
1751                                 return (PolicyEntity)policyQueryList.get(0);
1752                         }
1753                 }
1754
1755                 @Override
1756                 public void renamePolicy(String oldPath, String newPath,String username){
1757 /*                      String[] oldPolicy = getScopeAndNameAndType(oldPath);
1758                         String[] newPolicy = getScopeAndNameAndType(newPath);
1759                         if(oldPolicy == null || newPolicy == null){
1760                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
1761                                                 +oldPath+", "+newPath);
1762                                 throw new IllegalArgumentException("Could not parse one or more of the path names");
1763                         }
1764                         synchronized (emLock) {
1765                                 checkBeforeOperationRun();
1766
1767                                 PolicyEntity existingPolicy;
1768                                 boolean existingPolicyDeleted = false;
1769                                 List<?> groups = null;
1770                                 try{
1771                                         existingPolicy = getPolicy(newPolicy[1],newPolicy[0]);
1772                                 } catch(Exception e){
1773                                         existingPolicy = null;
1774                                 }
1775                                 if(existingPolicy != null && !existingPolicy.isDeleted()){
1776                                         logger.error("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
1777                                         throw new IllegalArgumentException("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy);
1778                                 } else if(existingPolicy != null && existingPolicy.isDeleted()){
1779                                         try{
1780                                                 Query getGroups = em.createQuery("SELECT g FROM GroupEntity g JOIN g.policies p WHERE p.policyId=:pid");
1781
1782                                                 getGroups.setParameter("pid", existingPolicy.getPolicyId());
1783                                                 groups = getGroups.getResultList();
1784                                         }catch(Exception e){
1785                                                 groups = new LinkedList<>();
1786                                         }
1787                                         for(Object o : groups){
1788                                                 GroupEntity group = (GroupEntity)o;
1789                                                 group.removePolicyFromGroup(existingPolicy);
1790                                         }
1791                                         try{
1792                                                 em.flush();
1793                                         }catch(Exception e){
1794                                                 logger.error("Error while removing the policy from groups: "+existingPolicy.getPolicyName());
1795                                         }
1796                                         try{
1797                                                 em.remove(existingPolicy);
1798                                                 em.flush();
1799                                         }catch(Exception e){
1800                                                 logger.error("Could not remove the existing deleted policy: "+existingPolicy.getPolicyName());
1801                                         }
1802                                         existingPolicyDeleted = true;
1803                                         //create the new policy
1804                                         //for each of the groups, add the new policy
1805                                 }
1806
1807                                 PolicyEntity policyToRename;
1808                                 try{
1809                                         policyToRename = getPolicy(oldPolicy[1],oldPolicy[0]);
1810                                 } catch(Exception e){
1811                                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to rename: "
1812                                                         +oldPolicy[1]);
1813                                         throw new PersistenceException("Could not get policy record to rename");
1814                                 }
1815                                 String policyDataString = null;
1816                                 InputStream fileContentStream = null;
1817                                 String policyFilePath = Paths.get(oldPath).toAbsolutePath().toString();
1818                                 //I want to try the old path first, then if it doesn't work, try the new path
1819                                 for(int i=0;i<2;i++){
1820                                         try {
1821                                                 fileContentStream = new FileInputStream(policyFilePath);
1822                                                 policyDataString = IOUtils.toString(fileContentStream);
1823                                         } catch (FileNotFoundException e) {
1824                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+policyFilePath+")");
1825                                                 //if we can't find the oldPath, we'll try the new path
1826                                                 if(i == 0){
1827                                                         policyFilePath = Paths.get(newPath).toAbsolutePath().toString();
1828                                                         continue;
1829                                                 }
1830                                                 throw new IllegalArgumentException("The file path does not exist");
1831                                         } catch(IOException e2){
1832                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")");
1833                                                 throw new IllegalArgumentException("The file path cannot be read");
1834                                         } finally {
1835                                                 IOUtils.closeQuietly(fileContentStream);
1836                                         }
1837                                         if(policyDataString == null){
1838                                                 throw new IllegalArgumentException("The file path cannot be read");
1839                                         }
1840                                         //escape the loop
1841                                         i=2;
1842                                 }
1843                                 policyToRename.setPolicyName(newPolicy[1]);
1844                                 policyToRename.setPolicyData(policyDataString);
1845                                 policyToRename.setScope(newPolicy[0]);
1846                                 policyToRename.setModifiedBy(username);
1847                                 if(policyToRename.getConfigurationData() != null){
1848                                         String configType = policyToRename.getConfigurationData().getConfigType();
1849                                         policyToRename.getConfigurationData().setConfigurationName(getConfigFile(newPolicy[1], configType));
1850                                         policyToRename.getConfigurationData().setModifiedBy(username);
1851                                 }
1852                                 if(policyToRename.getActionBodyEntity() != null){
1853                                         String newActionName = newPolicy[0]+"."+removeFileExtension(newPolicy[1])+".json";
1854                                         policyToRename.getActionBodyEntity().setActionBodyName(newActionName);
1855                                         policyToRename.getActionBodyEntity().setModifiedBy(username);
1856                                 }
1857                                 if(existingPolicyDeleted){
1858                                         for(Object o : groups){
1859
1860                                                 GroupEntity group = (GroupEntity)o;
1861                                                 group.addPolicyToGroup(policyToRename);
1862                                         }
1863                                 }
1864                                 em.flush();
1865                                 this.policyId = policyToRename.getPolicyId();
1866                                 this.newGroupId = oldPath;
1867                         }*/
1868                 }
1869
1870                 @Override
1871                 public GroupEntity getGroup(long groupKey){
1872                         logger.debug("getGroup(int groupKey) as getGroup("+groupKey+") called");
1873                         if(groupKey < 0){
1874                                 throw new IllegalArgumentException("groupKey must be at least 0");
1875                         }
1876                         synchronized(emLock){
1877                                 checkBeforeOperationRun(true);
1878                                 //check if group exists
1879                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey");
1880                                 groupQuery.setParameter("groupKey", groupKey);                  
1881                                 List<?> groupQueryList;
1882                                 try{
1883                                         groupQueryList = groupQuery.getResultList();
1884                                 }catch(Exception e){
1885                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
1886                                         throw new PersistenceException("Query failed trying to get group "+groupKey);
1887                                 }
1888                                 if(groupQueryList.size() < 1){
1889                                         PolicyLogger.error("Group does not exist with groupKey "+groupKey);
1890                                         throw new PersistenceException("Group does not exist with groupKey "+groupKey);
1891                                 } else if(groupQueryList.size() > 1){
1892                                         PolicyLogger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
1893                                         throw new PersistenceException("Somehow, more than one group with the groupKey "+groupKey+" were found in the database");
1894                                 }
1895                                 return (GroupEntity)groupQueryList.get(0);
1896                         }
1897                 }
1898
1899                 @Override
1900                 public GroupEntity getGroup(String groupId){
1901                         logger.debug("getGroup(String groupId) as getGroup("+groupId+") called");
1902                         if(isNullOrEmpty(groupId)){
1903                                 throw new IllegalArgumentException("groupId must not be null or empty");
1904                         }
1905                         synchronized(emLock){
1906                                 checkBeforeOperationRun(true);
1907                                 //check if group exists
1908                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId");
1909                                 groupQuery.setParameter("groupId", groupId);                    
1910                                 List<?> groupQueryList;
1911                                 try{
1912                                         groupQueryList = groupQuery.getResultList();
1913                                 }catch(Exception e){
1914                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()");
1915                                         throw new PersistenceException("Query failed trying to get group "+groupId);
1916                                 }
1917                                 if(groupQueryList.size() < 1){
1918                                         PolicyLogger.error("Group does not exist with id "+groupId);
1919                                         throw new PersistenceException("Group does not exist with id "+groupId);
1920                                 } else if(groupQueryList.size() > 1){
1921                                         PolicyLogger.error("Somehow, more than one group with the id "+groupId+" were found in the database");
1922                                         throw new PersistenceException("Somehow, more than one group with the id "+groupId+" were found in the database");
1923                                 }
1924                                 return (GroupEntity)groupQueryList.get(0);
1925                         }
1926                 }
1927                 @Override
1928                 public List<?> getPdpsInGroup(long groupKey){
1929                         logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup("+groupKey+") called");
1930                         if(groupKey < 0){
1931                                 throw new IllegalArgumentException("groupId must not be < 0");
1932                         }                       
1933                         synchronized(emLock){
1934                                 checkBeforeOperationRun(true);
1935                                 Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group");
1936                                 pdpsQuery.setParameter("group", getGroup(groupKey));
1937                                 return pdpsQuery.getResultList();
1938                         }
1939                 }
1940                 @Override
1941                 public PdpEntity getPdp(long pdpKey){
1942                         logger.debug("getPdp(int pdpKey) as getPdp("+pdpKey+") called");
1943                         if(pdpKey < 0){
1944                                 throw new IllegalArgumentException("pdpKey must be at least 0");
1945                         }
1946                         synchronized(emLock){
1947                                 checkBeforeOperationRun(true);
1948                                 //check if group exists
1949                                 Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey");
1950                                 pdpQuery.setParameter("pdpKey", pdpKey);                        
1951                                 List<?> pdpQueryList;
1952                                 try{
1953                                         pdpQueryList = pdpQuery.getResultList();
1954                                 }catch(Exception e){
1955                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp with pdpQuery.getResultList()");
1956                                         throw new PersistenceException("Query failed trying to get pdp "+pdpKey);
1957                                 }
1958                                 if(pdpQueryList.size() < 1){
1959                                         PolicyLogger.error("Pdp does not exist with pdpKey "+pdpKey);
1960                                         throw new PersistenceException("Pdp does not exist with pdpKey "+pdpKey);
1961                                 } else if(pdpQueryList.size() > 1){
1962                                         PolicyLogger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
1963                                         throw new PersistenceException("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database");
1964                                 }
1965                                 return (PdpEntity)pdpQueryList.get(0);
1966                         }
1967                 }
1968                 
1969                 public void deletePolicy(String policyToDeletes){
1970                         /*synchronized(emLock){
1971                                 checkBeforeOperationRun();
1972                                 logger.debug("deletePolicy(String policyToDeletes) as deletePolicy("+policyToDeletes+") called");
1973                                 String[] scopeNameAndType = getScopeAndNameAndType(policyToDeletes);
1974                                 if(scopeNameAndType == null){
1975                                         throw new IllegalArgumentException("Could not parse file path");
1976                                 }
1977                                 String realScope = scopeNameAndType[0];
1978                                 String realName = scopeNameAndType[1];
1979                                 Query deletePolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName AND p.deleted=:deleted");                      
1980                                 deletePolicyQuery.setParameter("scope",realScope);
1981                                 deletePolicyQuery.setParameter("policyName", realName);
1982                                 deletePolicyQuery.setParameter("deleted", false);
1983                                 List<?> deletePolicyQueryList = deletePolicyQuery.getResultList();
1984                                 if(deletePolicyQueryList.size() < 1){
1985                                         logger.warn("The policy being deleted could not be found.");
1986                                         return;
1987                                 } else if(deletePolicyQueryList.size() > 1){
1988                                         PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1989                                         throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1990                                 } else {
1991                                         PolicyEntity policyToDelete = (PolicyEntity)deletePolicyQueryList.get(0);
1992                                         policyToDelete.setDeleted(true);
1993                                         if(policyToDelete.getConfigurationData() != null){
1994                                                 ConfigurationDataEntity cde = em.find(ConfigurationDataEntity.class,policyToDelete.getConfigurationData().getConfigurationDataId());                                    
1995                                                 if(cde != null){
1996                                                         cde.setDeleted(true);
1997                                                 }
1998                                         }
1999                                         if(policyToDelete.getActionBodyEntity() != null){
2000                                                 ActionBodyEntity abe = em.find(ActionBodyEntity.class,policyToDelete.getActionBodyEntity().getActionBodyId());                                  
2001                                                 if(abe != null){
2002                                                         abe.setDeleted(true);
2003                                                 }
2004                                         }
2005
2006                                         em.flush();
2007                                         this.policyId = policyToDelete.getPolicyId();
2008
2009                                 }
2010                         }
2011 */
2012                 }
2013
2014
2015                 @Override
2016                 public boolean isTransactionOpen() {
2017                         logger.debug("isTransactionOpen() as isTransactionOpen() called");
2018                         synchronized(emLock){
2019                                 return em.isOpen() && em.getTransaction().isActive();   
2020                         }
2021                 }
2022
2023
2024                 @Override
2025                 public void clonePolicy(String oldPolicyPath, String newPolicyPath, String username){
2026                         /*String[] oldPolicyData = getScopeAndNameAndType(oldPolicyPath);
2027                         String[] newPolicyData = getScopeAndNameAndType(newPolicyPath);
2028                         if(oldPolicyData == null || newPolicyData == null){
2029                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: "
2030                                                 +oldPolicyPath+", "+newPolicyPath);
2031                                 throw new IllegalArgumentException("Could not parse the oldPolicyPath or newPolicyPath");
2032                         }
2033                         PolicyEntity oldPolicy;
2034                         try{
2035                                 oldPolicy = getPolicy(oldPolicyData[1],oldPolicyData[0]);
2036                         }catch(Exception e){
2037                                 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to clone: "
2038                                                 +oldPolicyData[1]);
2039                                 throw new PersistenceException("Could not get policy record to clone");
2040                         }
2041                         ConfigurationDataEntity clonedConfig = null;
2042                         if(oldPolicy.getConfigurationData() != null){
2043                                 clonedConfig = new ConfigurationDataEntity();
2044                                 em.persist(clonedConfig);
2045                                 clonedConfig.setConfigBody(oldPolicy.getConfigurationData().getConfigBody());
2046                                 clonedConfig.setConfigType(oldPolicy.getConfigurationData().getConfigType());
2047                                 clonedConfig.setCreatedBy(username);
2048                                 clonedConfig.setConfigurationName(getConfigFile(newPolicyData[1], oldPolicy.getConfigurationData().getConfigType()));
2049                                 clonedConfig.setDescription(oldPolicy.getConfigurationData().getDescription());
2050                                 clonedConfig.setModifiedBy(username);
2051                                 em.flush();
2052                         }
2053                         ActionBodyEntity clonedAction = null;
2054                         if(oldPolicy.getActionBodyEntity() != null){
2055                                 clonedAction = new ActionBodyEntity();
2056                                 em.persist(clonedAction);
2057                                 clonedAction.setActionBody(oldPolicy.getActionBodyEntity().getActionBody());
2058                                 clonedAction.setActionBodyName(newPolicyData[0]+"."+newPolicyData[1]+".json");
2059                                 clonedAction.setCreatedBy(username);
2060                                 clonedAction.setModifiedBy(username);
2061                                 em.flush();
2062                         }                       
2063
2064 */
2065                 }
2066
2067                 private String processConfigPath(String configPath){
2068                         String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS);
2069                         if(webappsPath == null){
2070                                 logger.error("Webapps property does not exist");
2071                                 throw new IllegalArgumentException("Webapps property does not exist");
2072                         }
2073                         configPath = configPath.replace("$URL", webappsPath);
2074                         //make sure the correct slashes are in
2075                         try{
2076                                 configPath = Paths.get(configPath).toString();
2077                         } catch(InvalidPathException e){
2078                                 logger.error("Invalid config path: "+configPath);
2079                                 throw new IllegalArgumentException("Invalid config path: "+configPath);
2080                         }
2081                         return configPath;
2082                 }
2083                 private String readConfigFile(String configPath){
2084                         String configDataString = null;
2085                         InputStream configContentStream = null;
2086                         try {
2087                                 configContentStream = new FileInputStream(configPath);
2088                                 configDataString = IOUtils.toString(configContentStream);
2089                         } catch (FileNotFoundException e) {
2090                                 logger.error("Caught FileNotFoundException on new FileInputStream("+configPath+")",e);
2091                                 throw new IllegalArgumentException("The config file path does not exist");
2092                         } catch(IOException e2){
2093                                 logger.error("Caught IOException on newIOUtils.toString("+configContentStream+")",e2);
2094                                 throw new IllegalArgumentException("The config file path cannot be read");
2095                         } finally {
2096                                 IOUtils.closeQuietly(configContentStream);
2097                         }
2098                         if(configDataString == null){
2099                                 throw new IllegalArgumentException("The config file path cannot be read");
2100                         }
2101                         return configDataString;
2102                 }
2103
2104                 @Override
2105                 public void createPolicy(Policy policy, String username){
2106                         logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy("+policy+","+username+") called");
2107                         String policyScope = policy.policyAdapter.getDomainDir().replace(File.separator, ".");
2108                         //Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
2109                         //and this transaction is intercepted up stream.
2110                         InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType)policy.getCorrectPolicyDataObject());
2111                         String policyDataString;
2112                         try {
2113                                 policyDataString = IOUtils.toString(policyXmlStream);
2114                         } catch (IOException e) {
2115                                 policyDataString = "could not read";
2116                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught IOException on IOUtils.toString("+policyXmlStream+")");
2117                                 throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter.");
2118                         }
2119                         IOUtils.closeQuietly(policyXmlStream);
2120                         String configPath = "";
2121                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
2122                                 configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
2123                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
2124                                 configPath = evaluateXPath("/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " +policy.policyAdapter.getActionAttribute()+ ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", policyDataString);
2125                         }
2126
2127                         String prefix = null;
2128                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) {
2129
2130                                 prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName()));
2131                                 if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){
2132                                         String configData = "";
2133                                         try{
2134                                                 String newConfigPath = configPath;
2135                                                 try{
2136                                                         newConfigPath = processConfigPath(newConfigPath);                                                       
2137                                                 }catch(Exception e2){
2138                                                         logger.error("Could not process config path: "+newConfigPath,e2);
2139                                                 }
2140                                                 configData = readConfigFile(newConfigPath);
2141                                         }catch(Exception e){
2142                                                 logger.error("Could not read config body data for "+configPath,e);
2143                                         }
2144                                         policy.policyAdapter.setConfigBodyData(configData);
2145                                 }
2146                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) {
2147                                 prefix = "Action_";
2148                         } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Decision")) {
2149                                 prefix = "Decision_";
2150                         }
2151
2152                         if(!(policy.policyAdapter.getData() instanceof PolicyType)){
2153                                 PolicyLogger.error("The data field is not an instance of PolicyType");
2154                                 throw new IllegalArgumentException("The data field is not an instance of PolicyType");
2155                         }
2156                         String finalName = policyScope + "." + prefix+policy.policyAdapter.getPolicyName()+"."+((PolicyType)policy.policyAdapter.getData()).getVersion()+".xml";
2157                         if(policy.policyAdapter.getConfigType() == null || policy.policyAdapter.getConfigType().equals("")){
2158                                 //get the config file extension
2159                                 String ext = "";
2160                                 if (configPath != null) {
2161                                         if (!configPath.equalsIgnoreCase("")) {
2162                                                 ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());;
2163                                         }
2164                                 }
2165
2166                                 if(ext.contains("txt")){
2167                                         policy.policyAdapter.setConfigType(OTHER_CONFIG);
2168                                 } else if(ext.contains("json")){
2169                                         policy.policyAdapter.setConfigType(JSON_CONFIG);
2170                                 } else if(ext.contains("xml")){
2171                                         policy.policyAdapter.setConfigType(XML_CONFIG);
2172                                 } else if(ext.contains("properties")){
2173                                         policy.policyAdapter.setConfigType(PROPERTIES_CONFIG);
2174                                 } else {
2175                                         if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")){
2176                                                 policy.policyAdapter.setConfigType(JSON_CONFIG);
2177                                         }
2178                                 }
2179                         }
2180                         if(policyXmlStream != null){
2181                                 try {
2182                                         policyXmlStream.close();
2183                                 } catch (IOException e) {
2184                                         logger.error("Exception Occured while closing input stream"+e);
2185                                 }
2186                         }
2187                         createPolicy(policy.policyAdapter, username, policyScope,finalName,policyDataString);
2188
2189                 }
2190
2191                 @Override
2192                 public void close(){
2193                         synchronized(emLock){
2194                                 if(em.isOpen()){
2195                                         if(em.getTransaction().isActive()){
2196                                                 em.getTransaction().rollback();
2197                                         }
2198                                         em.close();
2199                                 }
2200                                 if(transactionTimer instanceof Thread){
2201                                         transactionTimer.interrupt();
2202                                 }
2203                         }
2204                 }
2205
2206
2207
2208                 @Override
2209                 public void createGroup(String groupId, String groupName, String groupDescription, String username) {
2210                         logger.debug("deletePolicy(String policyToDeletes) as createGroup("+groupId+", "+groupName+", "+groupDescription+") called");
2211                         if(isNullOrEmpty(groupId, groupName, username)){
2212                                 throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty");
2213                         }
2214                         if(!(groupDescription instanceof String)){
2215                                 groupDescription = "";
2216                         }
2217
2218                         synchronized(emLock){
2219                                 checkBeforeOperationRun();
2220                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2221                                 checkGroupQuery.setParameter("groupId", groupId);
2222                                 checkGroupQuery.setParameter("deleted", false);
2223                                 List<?> checkGroupQueryList;
2224                                 try{
2225                                         checkGroupQueryList = checkGroupQuery.getResultList();
2226                                 } catch(Exception e){
2227                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
2228                                         throw new PersistenceException("Query failed trying to check for existing group");
2229                                 }
2230                                 if(checkGroupQueryList.size() > 0){
2231                                         PolicyLogger.error("The group being added already exists with id "+groupId);
2232                                         throw new PersistenceException("The group being added already exists with id "+groupId);
2233                                 }
2234                                 GroupEntity newGroup = new GroupEntity();
2235                                 em.persist(newGroup);
2236                                 newGroup.setCreatedBy(username);
2237                                 newGroup.setModifiedBy(username);
2238                                 newGroup.setGroupName(groupName);
2239                                 newGroup.setGroupId(groupId);
2240                                 newGroup.setDescription(groupDescription);
2241
2242                                 em.flush();
2243                                 this.groupId = newGroup.getGroupKey();
2244                         }
2245                 }
2246
2247                 @Override
2248                 public void updateGroup(EcompPDPGroup group, String username){
2249                         logger.debug("updateGroup(PDPGroup group) as updateGroup("+group+","+username+") called");
2250                         if(group == null){
2251                                 throw new IllegalArgumentException("PDPGroup group must not be null");
2252                         }
2253                         if(isNullOrEmpty(group.getId(), username)){
2254                                 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
2255                         }
2256
2257                         synchronized(emLock){
2258                                 checkBeforeOperationRun();
2259                                 Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2260                                 getGroupQuery.setParameter("groupId", group.getId());
2261                                 getGroupQuery.setParameter("deleted", false);
2262                                 List<?> getGroupQueryList;
2263                                 try{
2264                                         getGroupQueryList = getGroupQuery.getResultList();
2265                                 } catch(Exception e){
2266                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
2267                                         throw new PersistenceException("Query failed trying to get group "+group.getId()+" for editing");
2268                                 }
2269                                 if(getGroupQueryList.size() < 1){
2270                                         PolicyLogger.error("The group cannot be found to update with id "+group.getId());
2271                                         throw new PersistenceException("The group cannot be found to update with id "+group.getId());
2272                                 } else if(getGroupQueryList.size() > 1){
2273                                         PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
2274                                         throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
2275                                 }
2276                                 GroupEntity groupToUpdate = (GroupEntity)getGroupQueryList.get(0);
2277                                 if(!stringEquals(groupToUpdate.getModifiedBy(), username)){
2278                                         groupToUpdate.setModifiedBy(username);
2279                                 }
2280                                 if(group.getDescription() != null && !stringEquals(group.getDescription(),groupToUpdate.getDescription())){
2281                                         groupToUpdate.setDescription(group.getDescription());
2282                                 }
2283                                 //let's find out what policies have been deleted
2284                                 StdPDPGroup oldGroup = null;
2285                                 try {
2286                                         oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId());
2287                                 } catch (PAPException e1) {
2288                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "We cannot get the group from the papEngine to delete policies");
2289                                 }
2290                                 if(oldGroup == null){
2291                                         PolicyLogger.error("We cannot get the group from the papEngine to delete policies");
2292                                 } else {
2293
2294                                         Set<String> newPolicySet = new HashSet<>(group.getPolicies().size());
2295                                         //a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison
2296                                         for(PDPPolicy pol: group.getPolicies()){
2297                                                 newPolicySet.add(pol.getId());
2298                                         }
2299                                         for(PDPPolicy pol : oldGroup.getPolicies()){
2300                                                 //should be fast since getPolicies uses a HashSet in StdPDPGroup
2301                                                 if(!newPolicySet.contains(pol.getId())){
2302                                                         String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId());
2303                                                         PolicyEntity policyToDelete;
2304                                                         try{
2305                                                                 policyToDelete = getPolicy(scopeAndName[0],scopeAndName[1]);
2306                                                         }catch(Exception e){
2307                                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get policy to remove: "+pol.getId());
2308                                                                 throw new PersistenceException("Could not get policy to remove: "+pol.getId());
2309                                                         }
2310                                                         groupToUpdate.getPolicies().remove(policyToDelete);
2311
2312                                                 }
2313                                         }
2314                                 }
2315                                 if(group.getName() != null && !stringEquals(group.getName(),groupToUpdate.getgroupName())){
2316                                         //we need to check if the new id exists in the database
2317                                         String newGroupId = createNewPDPGroupId(group.getName());
2318                                         Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2319                                         checkGroupQuery.setParameter("groupId", newGroupId);
2320                                         checkGroupQuery.setParameter("deleted", false);
2321                                         List<?> checkGroupQueryList;
2322                                         try{
2323                                                 checkGroupQueryList = checkGroupQuery.getResultList();
2324                                         } catch(Exception e){
2325                                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()");
2326                                                 throw new PersistenceException("Query failed trying to check for existing group");
2327                                         }
2328                                         if(checkGroupQueryList.size() != 0){
2329                                                 PolicyLogger.error("The new group name already exists, group id "+newGroupId);
2330                                                 throw new PersistenceException("The new group name already exists, group id "+newGroupId);
2331                                         }
2332                                         groupToUpdate.setGroupId(newGroupId);
2333                                         groupToUpdate.setGroupName(group.getName());
2334                                         this.newGroupId = group.getId();
2335                                 }
2336
2337                                 em.flush();
2338                                 this.groupId = groupToUpdate.getGroupKey();
2339                         }
2340                 }
2341
2342                 @Override
2343                 public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) {
2344                         logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup("+pdpID+", "+groupID+", "+pdpName+", "+pdpDescription+", "+pdpJmxPort+", "+username+") called");
2345                         if(isNullOrEmpty(pdpID, groupID,pdpName,username)){
2346                                 throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty");
2347                         }
2348                         if(!(pdpDescription instanceof String)){
2349                                 pdpDescription = "";
2350                         }
2351                         synchronized(emLock){
2352                                 checkBeforeOperationRun();
2353                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2354                                 checkGroupQuery.setParameter("groupId", groupID);
2355                                 checkGroupQuery.setParameter("deleted", false);
2356                                 List<?> checkGroupQueryList;
2357                                 try{
2358                                         checkGroupQueryList = checkGroupQuery.getResultList();
2359                                 } catch(Exception e){
2360                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()");
2361                                         throw new PersistenceException("Query failed trying to check for existing group");
2362                                 }
2363                                 if(checkGroupQueryList.size() != 1){
2364                                         PolicyLogger.error("The group does not exist");
2365                                         throw new PersistenceException("The group does not exist");
2366                                 }
2367                                 Query checkDuplicateQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
2368                                 checkDuplicateQuery.setParameter("pdpId", pdpID);
2369                                 checkDuplicateQuery.setParameter("deleted", false);
2370                                 List<?> checkDuplicateList;
2371                                 try{
2372                                         checkDuplicateList = checkDuplicateQuery.getResultList();
2373                                 } catch(Exception e){
2374                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()");
2375                                         throw new PersistenceException("Query failed trying to check for duplicate PDP "+pdpID);
2376                                 }
2377                                 PdpEntity newPdp;
2378                                 if(checkDuplicateList.size() > 0){
2379                                         logger.warn("PDP already exists with id "+pdpID);                               
2380                                         newPdp = (PdpEntity)checkDuplicateList.get(0);
2381                                 } else {
2382                                         newPdp = new PdpEntity();
2383                                         em.persist(newPdp);
2384                                 }                       
2385
2386                                 newPdp.setCreatedBy(username);
2387                                 newPdp.setDeleted(false);
2388                                 newPdp.setDescription(pdpDescription);
2389                                 newPdp.setGroup((GroupEntity)checkGroupQueryList.get(0));
2390                                 newPdp.setJmxPort(pdpJmxPort);
2391                                 newPdp.setModifiedBy(username);
2392                                 newPdp.setPdpId(pdpID);
2393                                 newPdp.setPdpName(pdpName);
2394
2395                                 em.flush();
2396                                 this.pdpId = newPdp.getPdpKey();
2397
2398                         }
2399                 }
2400
2401
2402                 @Override
2403                 public void updatePdp(EcompPDP pdp, String username){
2404                         logger.debug("updatePdp(PDP pdp, String username) as updatePdp("+pdp+","+username+") called");
2405                         if(pdp == null){
2406                                 throw new IllegalArgumentException("PDP pdp must not be null");
2407                         }
2408                         if(isNullOrEmpty(pdp.getId(),username)){
2409                                 throw new IllegalArgumentException("pdp.getId() and username must not be null or empty");
2410                         }
2411
2412                         synchronized(emLock){
2413                                 checkBeforeOperationRun();
2414                                 Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
2415                                 getPdpQuery.setParameter("pdpId", pdp.getId());
2416                                 getPdpQuery.setParameter("deleted", false);
2417                                 List<?> getPdpQueryList;
2418                                 try{
2419                                         getPdpQueryList = getPdpQuery.getResultList();
2420                                 } catch(Exception e){
2421                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
2422                                         throw new PersistenceException("Query failed trying to get PDP "+pdp.getId());
2423                                 }
2424                                 if(getPdpQueryList.size() < 1){
2425                                         PolicyLogger.error("The pdp cannot be found to update with id "+pdp.getId());
2426                                         throw new PersistenceException("The pdp cannot be found to update with id "+pdp.getId());
2427                                 } else if(getPdpQueryList.size() > 1){
2428                                         PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
2429                                         throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
2430                                 }
2431                                 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
2432                                 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
2433                                         pdpToUpdate.setModifiedBy(username);
2434                                 }
2435                                 if(pdp.getDescription() != null && !stringEquals(pdp.getDescription(),pdpToUpdate.getDescription())){
2436                                         pdpToUpdate.setDescription(pdp.getDescription());
2437                                 }
2438                                 if(pdp.getName() != null && !stringEquals(pdp.getName(),pdpToUpdate.getPdpName())){
2439                                         pdpToUpdate.setPdpName(pdp.getName());
2440                                 }
2441                                 if(pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())){
2442                                         pdpToUpdate.setJmxPort(pdp.getJmxPort());
2443                                 }
2444
2445                                 em.flush();
2446                                 this.pdpId = pdpToUpdate.getPdpKey();
2447                         }
2448                 }
2449
2450                 @Override
2451                 public void movePdp(EcompPDP pdp, EcompPDPGroup group, String username){
2452                         logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp("+pdp+","+group+","+username+") called");
2453                         if(pdp == null || group == null){
2454                                 throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null");
2455                         }
2456                         if(isNullOrEmpty(username,pdp.getId(),group.getId())){
2457                                 throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty");
2458                         }
2459
2460                         synchronized(emLock){
2461                                 checkBeforeOperationRun();
2462                                 //check if pdp exists
2463                                 Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
2464                                 getPdpQuery.setParameter("pdpId", pdp.getId());
2465                                 getPdpQuery.setParameter("deleted", false);
2466                                 List<?> getPdpQueryList;
2467                                 try{
2468                                         getPdpQueryList = getPdpQuery.getResultList();
2469                                 } catch(Exception e){
2470                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()");
2471                                         throw new PersistenceException("Query failed trying to get pdp to move with id "+pdp.getId());
2472                                 }
2473                                 if(getPdpQueryList.size() < 1){
2474                                         PolicyLogger.error("The pdp cannot be found to move with id "+pdp.getId());
2475                                         throw new PersistenceException("The pdp cannot be found to move with id "+pdp.getId());
2476                                 } else if(getPdpQueryList.size() > 1){
2477                                         PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
2478                                         throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database");
2479                                 }
2480
2481                                 //check if new group exists
2482                                 Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2483                                 checkGroupQuery.setParameter("groupId", group.getId());
2484                                 checkGroupQuery.setParameter("deleted", false);
2485                                 List<?> checkGroupQueryList;
2486                                 try{
2487                                         checkGroupQueryList = checkGroupQuery.getResultList();
2488                                 } catch(Exception e){
2489                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group on checkGroupQuery.getResultList()");
2490                                         throw new PersistenceException("Query failed trying to get new group "+group.getId());
2491                                 }
2492                                 if(checkGroupQueryList.size() != 1){
2493                                         PolicyLogger.error("The group "+group.getId()+" does not exist");
2494                                         throw new PersistenceException("The group "+group.getId()+" does not exist");
2495                                 }
2496                                 GroupEntity groupToMoveInto = (GroupEntity)checkGroupQueryList.get(0);
2497                                 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
2498                                 pdpToUpdate.setGroup(groupToMoveInto);
2499                                 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
2500                                         pdpToUpdate.setModifiedBy(username);
2501                                 }
2502
2503                                 em.flush();
2504                                 this.pdpId = pdpToUpdate.getPdpKey();
2505                         }
2506                 }
2507
2508                 @Override
2509                 public void changeDefaultGroup(EcompPDPGroup group, String username){
2510                         logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup("+group+","+username+") called");
2511                         if(group == null){
2512                                 throw new IllegalArgumentException("PDPGroup group must not be null");
2513                         }
2514                         if(isNullOrEmpty(group.getId(),username)){
2515                                 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
2516                         }
2517
2518                         synchronized(emLock){
2519                                 checkBeforeOperationRun();
2520                                 Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2521                                 getGroupQuery.setParameter("groupId", group.getId());
2522                                 getGroupQuery.setParameter("deleted", false);
2523                                 List<?> getGroupQueryList;
2524                                 try{
2525                                         getGroupQueryList = getGroupQuery.getResultList();
2526                                 } catch(Exception e){
2527                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()");
2528                                         throw new PersistenceException("Query failed trying to get group "+group.getId());
2529                                 }
2530                                 if(getGroupQueryList.size() < 1){
2531                                         PolicyLogger.error("The group cannot be found to set default with id "+group.getId());                          
2532                                         throw new PersistenceException("The group cannot be found to set default with id "+group.getId());
2533                                 } else if(getGroupQueryList.size() > 1){
2534                                         PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
2535                                         throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database");
2536                                 }
2537                                 GroupEntity newDefaultGroup = (GroupEntity)getGroupQueryList.get(0);
2538                                 newDefaultGroup.setDefaultGroup(true);
2539                                 if(!stringEquals(newDefaultGroup.getModifiedBy(), username)){
2540                                         newDefaultGroup.setModifiedBy(username);
2541                                 }
2542
2543                                 em.flush();
2544                                 this.groupId = newDefaultGroup.getGroupKey();
2545                                 Query setAllGroupsNotDefault = em.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g.groupKey<>:groupKey");
2546                                 //not going to set modified by for all groups
2547                                 setAllGroupsNotDefault.setParameter("defaultGroup", false);
2548                                 setAllGroupsNotDefault.setParameter("deleted", false);
2549                                 setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey());
2550                                 try{
2551                                         logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default");
2552                                 } catch(Exception e){
2553                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on setAllGroupsNotDefault.executeUpdate()");
2554                                         throw new PersistenceException("Could not set all other groups default to false");
2555                                 }
2556
2557                                 em.flush();
2558                         }
2559                 }
2560
2561
2562                 @Override
2563                 public void deleteGroup(EcompPDPGroup group, EcompPDPGroup moveToGroup, String username) throws PAPException {
2564                         logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called");
2565                         if(group == null){
2566                                 throw new IllegalArgumentException("PDPGroup group cannot be null");
2567                         }
2568                         if(isNullOrEmpty(username,group.getId())){
2569                                 throw new IllegalArgumentException("group.getId() and and username must not be null or empty");
2570                         }
2571
2572                         if(group.isDefaultGroup()){
2573                                 PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be.");
2574                                 throw new PAPException("You cannot delete the default group.");
2575                         }
2576                         synchronized(emLock){
2577                                 checkBeforeOperationRun();
2578                                 Query deleteGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2579                                 deleteGroupQuery.setParameter("groupId", group.getId());
2580                                 deleteGroupQuery.setParameter("deleted", false);
2581                                 List<?> deleteGroupQueryList;
2582                                 try{
2583                                         deleteGroupQueryList = deleteGroupQuery.getResultList();
2584                                 } catch(Exception e){
2585                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()");
2586                                         throw new PersistenceException("Query failed trying to check if group exists");
2587                                 }
2588                                 if(deleteGroupQueryList.size() < 1){
2589                                         logger.warn("The group could not be found with id " + group.getId());
2590                                         return;
2591                                 } else if(deleteGroupQueryList.size() > 1){
2592                                         PolicyLogger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
2593                                         throw new PersistenceException("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted");
2594                                 }                               
2595
2596                                 Query pdpsInGroupQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted");
2597                                 pdpsInGroupQuery.setParameter("group", ((GroupEntity)deleteGroupQueryList.get(0)));
2598                                 pdpsInGroupQuery.setParameter("deleted", false);
2599                                 List<?> pdpsInGroupList;
2600                                 try{
2601                                         pdpsInGroupList = pdpsInGroupQuery.getResultList();
2602                                 } catch(Exception e){
2603                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()");
2604                                         throw new PersistenceException("Query failed trying to get PDPs in group");
2605                                 }
2606                                 if(pdpsInGroupList.size() > 0){
2607                                         if(moveToGroup != null){
2608                                                 Query checkMoveToGroupQuery = em.createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted");
2609                                                 checkMoveToGroupQuery.setParameter("groupId", moveToGroup.getId());
2610                                                 checkMoveToGroupQuery.setParameter("deleted", false);
2611                                                 List<?> checkMoveToGroupList;
2612                                                 try{
2613                                                         checkMoveToGroupList = checkMoveToGroupQuery.getResultList();
2614                                                 } catch(Exception e){
2615                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()");
2616                                                         throw new PersistenceException("Query failed trying to check if group exists");
2617                                                 }
2618                                                 if(checkMoveToGroupList.size() < 1){
2619                                                         PolicyLogger.error("The group could not be found with id " + moveToGroup.getId());
2620                                                         throw new PersistenceException("The group could not be found with id " + moveToGroup.getId());
2621                                                 } else if(checkMoveToGroupList.size() > 1){
2622                                                         PolicyLogger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
2623                                                         throw new PersistenceException("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted");
2624                                                 } else {
2625                                                         GroupEntity newGroup = (GroupEntity)checkMoveToGroupList.get(0);
2626                                                         for(Object pdpObject : pdpsInGroupList){
2627                                                                 PdpEntity pdp = (PdpEntity)pdpObject;
2628                                                                 pdp.setGroup(newGroup);
2629                                                                 if(!stringEquals(pdp.getModifiedBy(),username)){
2630                                                                         pdp.setModifiedBy(username);
2631                                                                 }
2632                                                                 try{
2633
2634                                                                         em.flush();
2635                                                                         this.newGroupId = newGroup.getGroupId();
2636                                                                 } catch(PersistenceException e){
2637                                                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PersistenceException trying to set pdp group to null on em.flush()");
2638                                                                         throw new PersistenceException("Query failed trying to set pdp group to ");
2639                                                                 }
2640                                                         }
2641                                                 }
2642                                         } else {
2643                                                 PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to");
2644                                                 throw new PAPException("Group has PDPs. Must provide a group for them to move to");
2645                                         }
2646                                 } 
2647
2648                                 //delete group here
2649                                 GroupEntity groupToDelete = (GroupEntity)deleteGroupQueryList.get(0);
2650                                 groupToDelete.setDeleted(true);
2651                                 if(!stringEquals(groupToDelete.getModifiedBy(), username)){
2652                                         groupToDelete.setModifiedBy(username);
2653                                 }
2654                                 em.flush();
2655                                 this.groupId = groupToDelete.getGroupKey();
2656                         }
2657                 }
2658
2659                 @Override
2660                 public void addPolicyToGroup(String groupID, String policyID, String username) {
2661                         logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called");
2662                         if(isNullOrEmpty(groupID, policyID, username)){
2663                                 throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty");
2664                         }
2665                         synchronized(emLock){
2666                                 checkBeforeOperationRun();
2667                                 //check if group exists
2668                                 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted");
2669                                 groupQuery.setParameter("groupId", groupID);
2670                                 groupQuery.setParameter("deleted", false);
2671                                 List<?> groupQueryList;
2672                                 try{
2673                                         groupQueryList = groupQuery.getResultList();
2674                                 }catch(Exception e){
2675                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()");
2676                                         throw new PersistenceException("Query failed trying to check if group "+groupID+" exists");
2677                                 }
2678                                 if(groupQueryList.size() < 1){
2679                                         PolicyLogger.error("Group policy is being added to does not exist with id "+groupID);
2680                                         throw new PersistenceException("Group policy is being added to does not exist with id "+groupID);
2681                                 } else if(groupQueryList.size() > 1){
2682                                         PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
2683                                         throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted");
2684                                 }
2685                                 //we need to convert the form of the policy id that is used groups into the form that is used 
2686                                 //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml)
2687                                 String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID);                     
2688                                 Query policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p.deleted=:deleted");
2689                                 policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]);
2690                                 policyQuery.setParameter("scope", policyNameScopeAndVersion[1]);                        
2691                                 policyQuery.setParameter("deleted", false);
2692                                 List<?> policyQueryList;
2693                                 try{
2694                                         policyQueryList = policyQuery.getResultList();
2695                                 } catch(Exception e){
2696                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if policy exists policyQuery.getResultList()");
2697                                         throw new PersistenceException("Query failed trying to check if policy "+policyNameScopeAndVersion[0]+" exists");
2698                                 }
2699                                 if(policyQueryList.size() < 1){
2700                                         PolicyLogger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
2701                                         throw new PersistenceException("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);                          
2702                                 } else if(policyQueryList.size() > 1){
2703                                         PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
2704                                         throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted");
2705                                 }
2706                                 GroupEntity group = (GroupEntity)groupQueryList.get(0);
2707                                 PolicyEntity policy = (PolicyEntity)policyQueryList.get(0);
2708                     Iterator<PolicyEntity> policyIt = group.getPolicies().iterator();
2709                     String policyName = getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0];
2710                     try{
2711                     while(policyIt.hasNext()){
2712                         PolicyEntity pol = policyIt.next();
2713                         if(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){
2714                             policyIt.remove();
2715                         }
2716                     }
2717                     }catch(Exception e){
2718                         PolicyLogger.error("Could not delete old versions for policy "+policy.getPolicyName()+", ID: "+policy.getPolicyId());
2719                     }
2720                                 group.addPolicyToGroup(policy);
2721                                 em.flush();
2722                         }
2723                 }
2724
2725                 //this means delete pdp not just remove from group
2726                 @Override
2727                 public void removePdpFromGroup(String pdpID, String username) {
2728                         logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup("+pdpID+","+username+") called");
2729                         if(isNullOrEmpty(pdpID,username)){
2730                                 throw new IllegalArgumentException("pdpID and username must not be null or empty");
2731                         }
2732                         synchronized(emLock){
2733                                 checkBeforeOperationRun();
2734                                 Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted");
2735                                 pdpQuery.setParameter("pdpId", pdpID);
2736                                 pdpQuery.setParameter("deleted", false);
2737                                 List<?> pdpList;
2738                                 try{
2739                                         pdpList = pdpQuery.getResultList();
2740                                 } catch(Exception e){
2741                                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if pdp exists  pdpQuery.getResultList()");
2742                                         throw new PersistenceException("Query failed trying to check if pdp "+pdpID+" exists");
2743                                 }
2744                                 if(pdpList.size() > 1){
2745                                         PolicyLogger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
2746                                         throw new PersistenceException("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted");
2747                                 } else if(pdpList.size() < 1){
2748                                         PolicyLogger.error("Pdp being removed does not exist with id "+pdpID);
2749                                         return;
2750                                 }
2751                                 PdpEntity pdp = (PdpEntity)pdpList.get(0);
2752                                 pdp.setGroup(null);
2753                                 if(!stringEquals(pdp.getModifiedBy(),username)){
2754                                         pdp.setModifiedBy(username);
2755                                 }
2756                                 pdp.setDeleted(true);
2757
2758                                 em.flush();
2759                                 this.pdpId = pdp.getPdpKey();
2760                         }
2761                 }
2762         }
2763
2764         private PolicyDBDao(){
2765
2766         }
2767         
2768         public static PolicyDBDaoTestClass getPolicyDBDaoTestClass(){
2769                 return new PolicyDBDao().new PolicyDBDaoTestClass();
2770         }
2771         
2772         final class PolicyDBDaoTestClass {
2773                 String getConfigFile(String filename, String scope, PolicyRestAdapter policy){
2774                         return scope + "." + PolicyDBDao.this.getConfigFile(filename, policy);
2775                 }
2776                 String computeScope(String fullPath, String pathToExclude){
2777                         return PolicyDBDao.computeScope(fullPath, pathToExclude);
2778                 }
2779                 String encryptPassword(String password) throws Exception{
2780                         return PolicyDBDao.encryptPassword(password);
2781                 }
2782                 String decryptPassword(String password) throws Exception{
2783                         return PolicyDBDao.decryptPassword(password);
2784                 }
2785                 String getDescriptionFromXacml(String xacmlData){
2786                         return PolicyDBDao.getDescriptionFromXacml(xacmlData);
2787                 }
2788         String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName){
2789             return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName);
2790         }
2791         }
2792
2793 }