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