ba8057102a76cada108c535229a4d9a3428227b1
[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-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pap.xacml.rest.components;
23
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.api.pap.PDPPolicy;
26 import com.att.research.xacml.util.XACMLProperties;
27 import java.io.ByteArrayInputStream;
28 import java.io.InputStream;
29 import java.net.URI;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Set;
39 import javax.persistence.PersistenceException;
40 import org.apache.commons.io.FilenameUtils;
41 import org.hibernate.Criteria;
42 import org.hibernate.LockMode;
43 import org.hibernate.Query;
44 import org.hibernate.Session;
45 import org.hibernate.SessionFactory;
46 import org.hibernate.criterion.Restrictions;
47 import org.onap.policy.common.logging.eelf.MessageCodes;
48 import org.onap.policy.common.logging.eelf.PolicyLogger;
49 import org.onap.policy.common.logging.flexlogger.FlexLogger;
50 import org.onap.policy.common.logging.flexlogger.Logger;
51 import org.onap.policy.rest.XACMLRestProperties;
52 import org.onap.policy.rest.adapter.PolicyRestAdapter;
53 import org.onap.policy.rest.dao.PolicyDBException;
54 import org.onap.policy.rest.jpa.ActionBodyEntity;
55 import org.onap.policy.rest.jpa.ConfigurationDataEntity;
56 import org.onap.policy.rest.jpa.DatabaseLockEntity;
57 import org.onap.policy.rest.jpa.GroupEntity;
58 import org.onap.policy.rest.jpa.PdpEntity;
59 import org.onap.policy.rest.jpa.PolicyDBDaoEntity;
60 import org.onap.policy.rest.jpa.PolicyEntity;
61 import org.onap.policy.utils.CryptoUtils;
62 import org.onap.policy.xacml.api.XACMLErrorConstants;
63 import org.onap.policy.xacml.api.pap.OnapPDP;
64 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
65 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
66 import org.onap.policy.xacml.std.pap.StdPDPGroup;
67 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
68 import org.springframework.beans.factory.annotation.Autowired;
69 import org.springframework.stereotype.Component;
70
71 @Component
72 public class PolicyDBDao {
73     private static final Logger logger = FlexLogger.getLogger(PolicyDBDao.class);
74     private List<?> otherServers;
75
76     public List<?> getOtherServers() {
77         return otherServers;
78     }
79
80     public void setOtherServers(List<?> otherServers) {
81         this.otherServers = otherServers;
82     }
83
84     private static PolicyDBDao currentInstance = null;
85     private PAPPolicyEngine papEngine;
86
87     public PAPPolicyEngine getPapEngine() {
88         return papEngine;
89     }
90
91     public static final String JSON_CONFIG = "JSON";
92     public static final String XML_CONFIG = "XML";
93     public static final String PROPERTIES_CONFIG = "PROPERTIES";
94     public static final String OTHER_CONFIG = "OTHER";
95     public static final String AUDIT_USER = "audit";
96
97     public static final String CONFIG = "Config";
98     public static final String ACTION = "Action";
99     public static final String GROUP_ID = "groupId";
100     public static final String DELETED = "deleted";
101     public static final String GROUPENTITY_SELECT =
102             "SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted";
103     public static final String PDPENTITY_SELECT =
104             "SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted";
105     public static final String GROUP_NOT_FOUND = "The group could not be found with id ";
106     public static final String FOUND_IN_DB_NOT_DEL = " were found in the database that are not deleted";
107     public static final String MORE_THAN_ONE_PDP = "Somehow, more than one pdp with the same id ";
108     public static final String DELETED_STATUS_FOUND = " and deleted status were found in the database";
109     public static final String DUPLICATE_GROUPID = "Somehow, more than one group with the same id ";
110     public static final String PDP_ID = "pdpId";
111     public static final String QUERY_FAILED_FOR_GROUP = "Query failed trying to check for existing group";
112     public static final String QUERY_FAILED_GET_GROUP = "Query failed trying to get group ";
113     public static final String SCOPE = "scope";
114     public static final String POLICYDBDAO_VAR = "PolicyDBDao";
115     public static final String DUP_POLICYID = "Somehow, more than one policy with the id ";
116     public static final String FOUND_IN_DB = " were found in the database";
117
118
119     public static boolean isJunit = false;
120
121     public static void setJunit(boolean isJunit) {
122         PolicyDBDao.isJunit = isJunit;
123     }
124
125     private static SessionFactory sessionfactory;
126
127     /**
128      * Gets the current instance of PolicyDBDao.
129      *
130      * @return The instance of PolicyDBDao or throws exception if the given instance is null.
131      * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance
132      *         (EntityManagerFactory emf) to get this.
133      */
134     public static PolicyDBDao getPolicyDBDaoInstance() {
135         logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called");
136         if (currentInstance != null) {
137             return currentInstance;
138         } else {
139             currentInstance = new PolicyDBDao("init");
140         }
141         return currentInstance;
142     }
143
144     public void setPapEngine(PAPPolicyEngine papEngine2) {
145         this.papEngine = papEngine2;
146     }
147
148     @Autowired
149     public PolicyDBDao(SessionFactory sessionFactory) {
150         PolicyDBDao.sessionfactory = sessionFactory;
151     }
152
153     public PolicyDBDao() {
154         // Default Constructor
155     }
156
157     public PolicyDBDao(String init) {
158         // not needed in this release
159         if (!register()) {
160             PolicyLogger
161                     .error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
162         }
163
164         otherServers = getRemotePolicyDBDaoList();
165         if (logger.isDebugEnabled()) {
166             logger.debug("Number of remote PolicyDBDao instances: " + otherServers.size());
167         }
168         if (otherServers.isEmpty()) {
169             logger.warn("List of PolicyDBDao servers is empty or could not be retrieved");
170         }
171     }
172
173     // not static because we are going to be using the instance's emf
174     // waitTime in ms to wait for lock, or -1 to wait forever (no)
175     @SuppressWarnings("deprecation")
176     public void startTransactionSynced(Session session, int waitTime) throws InterruptedException {
177         logger.debug("\n\nstartTransactionSynced(Hibernate Session,int waitTime) as " + "\n   startTransactionSynced("
178                 + session + "," + waitTime + ") called\n\n");
179         DatabaseLockEntity lock = null;
180         session.beginTransaction();
181         try {
182             if (logger.isDebugEnabled()) {
183                 logger.debug("\n\nstartTransactionSynced():" + "\n   ATTEMPT to get the DB lock" + "\n\n");
184             }
185             lock = (DatabaseLockEntity) session.get(DatabaseLockEntity.class, 1, LockMode.PESSIMISTIC_WRITE);
186             if (logger.isDebugEnabled()) {
187                 logger.debug("\n\nstartTransactionSynced():" + "\n   GOT the DB lock" + "\n\n");
188             }
189         } catch (Exception e) {
190             logger.error("Exception Occured" + e);
191         }
192         if (lock == null) {
193             throw new IllegalStateException(
194                     "The lock row does not exist in the table. Please create a primary key with value = 1.");
195         }
196
197     }
198
199     /**
200      * Gets the list of other registered PolicyDBDaos from the database
201      *
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         Session session = sessionfactory.openSession();
208         try {
209             Criteria cr = session.createCriteria(PolicyDBDaoEntity.class);
210             policyDBDaoEntityList = cr.list();
211         } catch (Exception e) {
212             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR,
213                     "Exception querying for other registered PolicyDBDaos");
214             logger.warn("List of remote PolicyDBDaos will be empty", e);
215         } finally {
216             try {
217                 session.close();
218             } catch (Exception e) {
219                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement" + e);
220             }
221         }
222         return policyDBDaoEntityList;
223     }
224
225     public PolicyDBDaoTransaction getNewTransaction() {
226         logger.debug("getNewTransaction() as getNewTransaction() called");
227         return new PolicyDbDaoTransactionInstance("init");
228     }
229
230     /*
231      * Because the normal transactions are not used in audits, we can use the same transaction
232      * mechanism to get a transaction and obtain the emlock and the DB lock. We just need to provide
233      * different transaction timeout values in ms because the audit will run longer than normal
234      * transactions.
235      */
236     public PolicyDBDaoTransaction getNewAuditTransaction() {
237         logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called");
238         // Use the standard transaction wait time in ms
239         int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
240         // Use the (extended) audit timeout time in ms
241         int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT));
242         return new PolicyDbDaoTransactionInstance(auditTimeoutMs, auditWaitMs);
243     }
244
245     /**
246      * Checks if two strings are equal. Null strings ARE allowed.
247      *
248      * @param one A String or null to compare
249      * @param two A String or null to compare
250      */
251     public static boolean stringEquals(String one, String two) {
252         logger.debug("stringEquals(String one, String two) as stringEquals(" + one + ", " + two + ") called");
253         if (one == null && two == null) {
254             return true;
255         }
256         if (one == null || two == null) {
257             return false;
258         }
259         return one.equals(two);
260     }
261
262     /**
263      * Returns the url of this local pap server, removing the username and password, if they are
264      * present
265      *
266      * @return The url of this local pap server
267      */
268     public String[] getPapUrlUserPass() {
269         logger.debug("getPapUrl() as getPapUrl() called");
270         String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
271         if (url == null) {
272             return null;
273         }
274         return splitPapUrlUserPass(url);
275     }
276
277     public String[] splitPapUrlUserPass(String url) {
278         String[] urlUserPass = new String[3];
279         String[] commaSplit = url.split(",");
280         urlUserPass[0] = commaSplit[0];
281         if (commaSplit.length > 2) {
282             urlUserPass[1] = commaSplit[1];
283             urlUserPass[2] = commaSplit[2];
284         }
285         if (urlUserPass[1] == null || "".equals(urlUserPass[1])) {
286             String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
287             if (usernamePropertyValue != null) {
288                 urlUserPass[1] = usernamePropertyValue;
289             }
290         }
291         if (urlUserPass[2] == null || "".equals(urlUserPass[2])) {
292             String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
293             if (passwordPropertyValue != null) {
294                 urlUserPass[2] = passwordPropertyValue;
295             }
296         }
297         // if there is no comma, for some reason there is no user name and
298         // password, so don't try to cut them off
299         return urlUserPass;
300     }
301
302     /**
303      * Register the PolicyDBDao instance in the PolicyDBDaoEntity table
304      *
305      * @return Boolean, were we able to register?
306      */
307     private boolean register() {
308         logger.debug("register() as register() called");
309         String[] url = getPapUrlUserPass();
310         // --- check URL length
311         if (url == null || url.length < 3) {
312             return false;
313         }
314         Session session = sessionfactory.openSession();
315         try {
316             startTransactionSynced(session, 1000);
317         } catch (InterruptedException | IllegalStateException e) {
318             logger.debug("\nPolicyDBDao.register() caught an IllegalStateException: \n" + e + "\n");
319             DatabaseLockEntity lock;
320             lock = (DatabaseLockEntity) session.get(DatabaseLockEntity.class, 1);
321             if (lock == null) {
322                 lock = new DatabaseLockEntity();
323                 lock.setKey(1);
324                 try {
325                     session.persist(lock);
326                     session.flush();
327                     session.getTransaction().commit();
328                     session.close();
329                 } catch (Exception e2) {
330                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR,
331                             "COULD NOT CREATE DATABASELOCK ROW.  WILL TRY ONE MORE TIME");
332                 }
333
334                 session = sessionfactory.openSession();
335                 try {
336                     startTransactionSynced(session, 1000);
337                 } catch (Exception e3) {
338                     String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING";
339                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, POLICYDBDAO_VAR, msg);
340                     throw new IllegalStateException("msg" + "\n" + e3);
341                 }
342             }
343         }
344         logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n");
345         PolicyDBDaoEntity foundPolicyDBDaoEntity = null;
346         Criteria cr = session.createCriteria(PolicyDBDaoEntity.class);
347         cr.add(Restrictions.eq("policyDBDaoUrl", url[0]));
348         List<?> data = cr.list();
349         if (!data.isEmpty()) {
350             foundPolicyDBDaoEntity = (PolicyDBDaoEntity) data.get(0);
351         }
352
353         // encrypt the password
354         String txt = null;
355         try {
356             txt = CryptoUtils.encryptTxt(url[2].getBytes(StandardCharsets.UTF_8));
357         } catch (Exception e) {
358             logger.debug(e);
359             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Could not encrypt PAP password");
360         }
361         if (foundPolicyDBDaoEntity == null) {
362             PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity();
363             newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]);
364             newPolicyDBDaoEntity.setDescription("PAP server at " + url[0]);
365             newPolicyDBDaoEntity.setUsername(url[1]);
366             newPolicyDBDaoEntity.setPassword(txt);
367             try {
368                 session.persist(newPolicyDBDaoEntity);
369                 session.getTransaction().commit();
370             } catch (Exception e) {
371                 logger.debug(e);
372                 try {
373                     session.getTransaction().rollback();
374                 } catch (Exception e2) {
375                     logger.debug(e2);
376                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR,
377                             "Could not add new PolicyDBDao to the database");
378                 }
379             }
380         } else {
381             // just want to update in order to change modified date
382             if (url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())) {
383                 foundPolicyDBDaoEntity.setUsername(url[1]);
384             }
385             if (txt != null && !stringEquals(txt, foundPolicyDBDaoEntity.getPassword())) {
386                 foundPolicyDBDaoEntity.setPassword(txt);
387             }
388             foundPolicyDBDaoEntity.preUpdate();
389             try {
390                 session.getTransaction().commit();
391             } catch (Exception e) {
392                 logger.debug(e);
393                 try {
394                     session.getTransaction().rollback();
395                 } catch (Exception e2) {
396                     logger.debug(e2);
397                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR,
398                             "Could not update PolicyDBDao in the database");
399                 }
400             }
401         }
402         session.close();
403         logger.debug("\nPolicyDBDao.register(). Success!!\n");
404         return true;
405     }
406
407     /*
408      * This method is called during all pushPolicy transactions and makes sure the file system group
409      * is in sync with the database groupentity
410      */
411     public StdPDPGroup synchronizeGroupPoliciesInFileSystem(StdPDPGroup pdpGroup, GroupEntity groupentity)
412             throws PAPException, PolicyDBException {
413
414         HashMap<String, PDPPolicy> currentPolicyMap = new HashMap<>();
415         HashSet<String> newPolicyIdSet = new HashSet<>();
416         HashSet<PDPPolicy> newPolicySet = new HashSet<>();
417
418         for (PDPPolicy pdpPolicy : pdpGroup.getPolicies()) {
419             currentPolicyMap.put(pdpPolicy.getId(), pdpPolicy);
420         }
421
422         for (PolicyEntity policy : groupentity.getPolicies()) {
423             String pdpPolicyId = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
424             newPolicyIdSet.add(pdpPolicyId);
425
426             if (currentPolicyMap.containsKey(pdpPolicyId)) {
427                 newPolicySet.add(currentPolicyMap.get(pdpPolicyId));
428             } else {
429                 // convert PolicyEntity object to PDPPolicy
430                 String name = pdpPolicyId.replace(".xml", "");
431                 name = name.substring(0, name.lastIndexOf('.'));
432                 InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
433                 pdpGroup.copyPolicyToFile(pdpPolicyId, name, policyStream);
434                 URI location = Paths.get(pdpGroup.getDirectory().toAbsolutePath().toString(), pdpPolicyId).toUri();
435                 StdPDPPolicy newPolicy = null;
436                 try {
437                     newPolicy = new StdPDPPolicy(pdpPolicyId, true,
438                             removeExtensionAndVersionFromPolicyName(pdpPolicyId), location);
439                     newPolicySet.add(newPolicy);
440                     logger.info("Adding new policy to PDPGroup - " + newPolicy.getId() + ", Location - " + location);
441                 } catch (Exception e) {
442                     logger.debug(e);
443                     PolicyLogger
444                             .error("PolicyDBDao: Exception occurred while creating the StdPDPPolicy newPolicy object "
445                                     + e.getMessage());
446                 }
447             }
448         }
449
450         for (String id : currentPolicyMap.keySet()) {
451             if (!newPolicyIdSet.contains(id)) {
452                 try {
453                     Files.delete(Paths.get(currentPolicyMap.get(id).getLocation()));
454                 } catch (Exception e) {
455                     logger.debug(e);
456                     PolicyLogger
457                             .error("PolicyDBDao: Exception occurred while attempting to delete the old version of the policy file from the group. "
458                                     + e.getMessage());
459                 }
460             }
461         }
462
463         logger.info("PolicyDBDao: Adding new policy set to group to keep filesystem and DB in sync");
464         pdpGroup.setPolicies(newPolicySet);
465
466         return pdpGroup;
467     }
468
469     public String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException {
470         return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0];
471     }
472
473     /**
474      * Splits apart the policy name and version from a policy file path
475      *
476      * @param originalPolicyName: a policy file name ex: Config_policy.2.xml
477      * @return An array [0]: The policy name, [1]: the policy version, as a string
478      */
479     public String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException {
480         String policyName = originalPolicyName;
481         String[] nameAndVersion = new String[2];
482         try {
483             policyName = removeFileExtension(policyName);
484             nameAndVersion[0] = policyName.substring(0, policyName.lastIndexOf('.'));
485             if (isNullOrEmpty(nameAndVersion[0])) {
486                 throw new PolicyDBException();
487             }
488         } catch (Exception e) {
489             nameAndVersion[0] = originalPolicyName;
490             logger.debug(e);
491         }
492         try {
493             nameAndVersion[1] = policyName.substring(policyName.lastIndexOf('.') + 1);
494             if (isNullOrEmpty(nameAndVersion[1])) {
495                 throw new PolicyDBException();
496             }
497         } catch (Exception e) {
498             nameAndVersion[1] = "1";
499             logger.debug(e);
500         }
501         return nameAndVersion;
502     }
503
504     public String getPdpPolicyName(String name, String scope) {
505         String finalName = "";
506         finalName += scope;
507         finalName += ".";
508         finalName += removeFileExtension(name);
509         finalName += ".xml";
510         return finalName;
511     }
512
513     private String removeFileExtension(String fileName) {
514         return fileName.substring(0, fileName.lastIndexOf('.'));
515     }
516
517     public void auditLocalDatabase(PAPPolicyEngine papEngine2) {
518         logger.debug("PolicyDBDao.auditLocalDatabase() is called");
519         try {
520             deleteAllGroupTables();
521             auditGroups(papEngine2);
522         } catch (Exception e) {
523             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "auditLocalDatabase() error");
524             logger.error("Exception Occured" + e);
525         }
526     }
527
528     public StdPDPGroup auditLocalFileSystem(StdPDPGroup group) {
529
530         logger.info("Starting Local File System group audit");
531         Session session = sessionfactory.openSession();
532         session.getTransaction().begin();
533
534         StdPDPGroup updatedGroup = null;
535         try {
536             Query groupQuery = session.createQuery(GROUPENTITY_SELECT);
537             groupQuery.setParameter(GROUP_ID, group.getId());
538             groupQuery.setParameter(DELETED, false);
539             List<?> groupQueryList = groupQuery.list();
540             if (groupQueryList != null && !groupQueryList.isEmpty()) {
541                 GroupEntity dbgroup = (GroupEntity) groupQueryList.get(0);
542                 updatedGroup = synchronizeGroupPoliciesInFileSystem(group, dbgroup);
543                 logger.info("Group was updated during file system audit: " + updatedGroup.toString());
544             }
545         } catch (PAPException | PolicyDBException e) {
546             logger.error(e);
547         } catch (Exception e) {
548             logger.error(e);
549             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR,
550                     "Caught Exception trying to check if group exists groupQuery.getResultList()");
551             throw new PersistenceException("Query failed trying to check if group " + group.getId() + " exists");
552         }
553
554         session.getTransaction().commit();
555         session.close();
556
557         return updatedGroup;
558     }
559
560     /*
561      * This method is called at startup to recreate config data from DB to the file system.
562      *
563      */
564     public void synchronizeConfigDataInFileSystem() {
565
566         logger.info("Starting Local File System Config data Sync");
567         // sync both web apps Config and Action
568         syncConfigData(ConfigurationDataEntity.class, CONFIG);
569         syncConfigData(ActionBodyEntity.class, ACTION);
570     }
571
572     private <T> void syncConfigData(Class<T> cl, String type) {
573         Session session = sessionfactory.openSession();
574         try {
575             final Criteria configDataQuery = session.createCriteria(cl.getName());
576             @SuppressWarnings("unchecked")
577             final List<T> configDataResult = configDataQuery.list();
578             Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS), type);
579
580             for (final T configData : configDataResult) {
581                 String configName = null;
582                 byte[] configBody;
583                 try {
584                     if (CONFIG.equalsIgnoreCase(type)) {
585                         configName = ((ConfigurationDataEntity) configData).getConfigurationName();
586                         configBody = (((ConfigurationDataEntity) configData).getConfigBody() != null)
587                                 ? ((ConfigurationDataEntity) configData).getConfigBody()
588                                         .getBytes(StandardCharsets.UTF_8)
589                                 : "".getBytes();
590                     } else {
591                         configName = ((ActionBodyEntity) configData).getActionBodyName();
592                         configBody = (((ActionBodyEntity) configData).getActionBody() != null)
593                                 ? ((ActionBodyEntity) configData).getActionBody().getBytes(StandardCharsets.UTF_8)
594                                 : "".getBytes();
595                     }
596                     Path filePath = Paths.get(webappsPath.toString(), configName);
597                     if (!filePath.toFile().exists()) {
598                         Files.write(filePath, configBody);
599                         logger.info("Created Config File from DB - " + filePath.toString());
600                     }
601                 } catch (Exception e) {
602                     // log and keep going
603                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR,
604                             "Exception occured while creating Configuration File - " + configName);
605                 }
606             }
607         } catch (final Exception exception) {
608             logger.error("Unable to synchronizeConfigDataInFileSystem", exception);
609         }
610         session.close();
611     }
612
613     public void deleteAllGroupTables() {
614         logger.debug("PolicyDBDao.deleteAllGroupTables() called");
615         Session session = sessionfactory.openSession();
616         session.getTransaction().begin();
617
618         Query deletePdpEntityEntityTableUpdate = session.getNamedQuery("PdpEntity.deleteAll");
619         deletePdpEntityEntityTableUpdate.executeUpdate();
620
621         Query deleteGroupEntityTableUpdate = session.getNamedQuery("GroupEntity.deleteAll");
622         deleteGroupEntityTableUpdate.executeUpdate();
623
624         session.getTransaction().commit();
625         session.close();
626     }
627
628     @SuppressWarnings("unchecked")
629     public void auditGroups(PAPPolicyEngine papEngine2) {
630         logger.debug("PolicyDBDao.auditGroups() called");
631
632         Session session = sessionfactory.openSession();
633         session.getTransaction().begin();
634         final String AUDIT_STR = "Audit";
635         try {
636
637             Set<OnapPDPGroup> groups = papEngine2.getOnapPDPGroups();
638
639             for (OnapPDPGroup grp : groups) {
640                 try {
641                     GroupEntity groupEntity = new GroupEntity();
642                     groupEntity.setGroupName(grp.getName());
643                     groupEntity.setDescription(grp.getDescription());
644                     groupEntity.setDefaultGroup(grp.isDefaultGroup());
645                     groupEntity.setCreatedBy(AUDIT_STR);
646                     groupEntity.setGroupId(createNewPDPGroupId(grp.getId()));
647                     groupEntity.setModifiedBy(AUDIT_STR);
648                     session.persist(groupEntity);
649                     Set<OnapPDP> pdps = grp.getOnapPdps();
650
651                     for (OnapPDP pdp : pdps) {
652                         PdpEntity pdpEntity = new PdpEntity();
653                         pdpEntity.setGroup(groupEntity);
654                         pdpEntity.setJmxPort(pdp.getJmxPort());
655                         pdpEntity.setPdpId(pdp.getId());
656                         pdpEntity.setPdpName(pdp.getName());
657                         pdpEntity.setModifiedBy(AUDIT_STR);
658                         pdpEntity.setCreatedBy(AUDIT_STR);
659                         session.persist(pdpEntity);
660                     }
661
662                     Set<PDPPolicy> policies = grp.getPolicies();
663
664                     for (PDPPolicy policy : policies) {
665                         try {
666                             String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId());
667                             if (stringArray == null) {
668                                 throw new IllegalArgumentException(
669                                         "Invalid input - policyID must contain name, scope and version");
670                             }
671                             List<PolicyEntity> policyEntityList;
672                             Query getPolicyEntitiesQuery = session.getNamedQuery("PolicyEntity.findByNameAndScope");
673                             getPolicyEntitiesQuery.setParameter("name", stringArray[0]);
674                             getPolicyEntitiesQuery.setParameter(SCOPE, stringArray[1]);
675
676                             policyEntityList = getPolicyEntitiesQuery.list();
677                             PolicyEntity policyEntity = null;
678                             if (!policyEntityList.isEmpty()) {
679                                 policyEntity = policyEntityList.get(0);
680                             }
681                             if (policyEntity != null) {
682                                 groupEntity.addPolicyToGroup(policyEntity);
683                             }
684                         } catch (Exception e2) {
685                             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR,
686                                     "Exception auditGroups inner catch");
687                         }
688                     }
689                 } catch (Exception e1) {
690                     PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, POLICYDBDAO_VAR,
691                             "Exception auditGroups middle catch");
692                 }
693             }
694         } catch (Exception e) {
695             session.getTransaction().rollback();
696             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Exception auditGroups outer catch");
697             session.close();
698             return;
699         }
700
701         session.getTransaction().commit();
702         session.close();
703
704     }
705
706     public String getConfigFile(String filename, PolicyRestAdapter policy) {
707         if (policy == null) {
708             return getConfigFile(filename, (String) null);
709         }
710         return getConfigFile(filename, policy.getConfigType());
711     }
712
713     // copied from ConfigPolicy.java and modified
714     // Here we are adding the extension for the configurations file based on the
715     // config type selection for saving.
716     public String getConfigFile(String inputFilename, String configType) {
717         String filename = inputFilename;
718         logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile(" + filename
719                 + ", " + configType + ") called");
720         filename = FilenameUtils.removeExtension(filename);
721         String id = configType;
722
723         if (id != null) {
724             if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) {
725                 filename = filename + ".json";
726             }
727             if (id.equals(ConfigPolicy.XML_CONFIG)) {
728                 filename = filename + ".xml";
729             }
730             if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) {
731                 filename = filename + ".properties";
732             }
733             if (id.equals(ConfigPolicy.OTHER_CONFIG)) {
734                 filename = filename + ".txt";
735             }
736         }
737         return filename;
738     }
739
740     public String[] getNameScopeAndVersionFromPdpPolicy(String fileName) {
741         String[] splitByDots = fileName.split("\\.");
742         if (splitByDots.length < 3) {
743             return null;
744         }
745         String policyName = splitByDots[splitByDots.length - 3];
746         String version = splitByDots[splitByDots.length - 2];
747         // policy names now include version
748         String scope = "";
749         for (int i = 0; i < splitByDots.length - 3; i++) {
750             scope += ".".concat(splitByDots[i]);
751         }
752         // remove the first dot
753         if (scope.length() > 0) {
754             scope = scope.substring(1);
755         }
756         String[] returnArray = new String[3];
757         returnArray[0] = policyName + "." + version + ".xml";
758         returnArray[2] = version;
759         returnArray[1] = scope;
760         return returnArray;
761     }
762
763     public static String createNewPDPGroupId(String name) {
764         String id = name;
765         // replace "bad" characters with sequences that will be ok for file
766         // names and properties keys.
767         id = id.replace(" ", "_sp_");
768         id = id.replace("\t", "_tab_");
769         id = id.replace("\\", "_bksl_");
770         id = id.replace("/", "_sl_");
771         id = id.replace(":", "_col_");
772         id = id.replace("*", "_ast_");
773         id = id.replace("?", "_q_");
774         id = id.replace("\"", "_quo_");
775         id = id.replace("<", "_lt_");
776         id = id.replace(">", "_gt_");
777         id = id.replace("|", "_bar_");
778         id = id.replace("=", "_eq_");
779         id = id.replace(",", "_com_");
780         id = id.replace(";", "_scom_");
781
782         return id;
783     }
784
785     /**
786      * Checks if any of the given strings are empty or null
787      *
788      * @param strings One or more Strings (or nulls) to check if they are null or empty
789      * @return true if one or more of the given strings are empty or null
790      */
791     public static boolean isNullOrEmpty(String... strings) {
792         for (String s : strings) {
793             if (s == null || "".equals(s)) {
794                 return true;
795             }
796         }
797         return false;
798     }
799
800     public static PolicyDBDaoTestClass getPolicyDBDaoTestClass() {
801         return new PolicyDBDao().new PolicyDBDaoTestClass();
802     }
803
804     final class PolicyDBDaoTestClass {
805         String getConfigFile(String filename, String scope, PolicyRestAdapter policy) {
806             return scope + "." + PolicyDBDao.this.getConfigFile(filename, policy);
807         }
808
809         String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException {
810             return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName);
811         }
812
813         String[] getNameScopeAndVersionFromPdpPolicy(String fileName) {
814             return PolicyDBDao.this.getNameScopeAndVersionFromPdpPolicy(fileName);
815         }
816
817         String getPdpPolicyName(String name, String scope) {
818             return PolicyDBDao.this.getPdpPolicyName(name, scope);
819         }
820     }
821
822 }