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