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