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