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