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