2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.policy.pap.xacml.rest.components;
24 import java.io.ByteArrayInputStream;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.StringReader;
32 import java.net.HttpURLConnection;
33 import java.net.MalformedURLException;
34 import java.net.ProtocolException;
37 import java.nio.charset.StandardCharsets;
38 import java.nio.file.Files;
39 import java.nio.file.InvalidPathException;
40 import java.nio.file.Path;
41 import java.nio.file.Paths;
42 import java.util.Base64;
43 import java.util.Date;
44 import java.util.HashMap;
45 import java.util.HashSet;
46 import java.util.Iterator;
47 import java.util.LinkedList;
48 import java.util.List;
51 import java.util.UUID;
53 import javax.persistence.EntityManager;
54 import javax.persistence.EntityManagerFactory;
55 import javax.persistence.LockModeType;
56 import javax.persistence.PersistenceException;
57 import javax.persistence.Query;
58 import javax.persistence.RollbackException;
59 import javax.xml.parsers.DocumentBuilder;
60 import javax.xml.parsers.DocumentBuilderFactory;
61 import javax.xml.xpath.XPath;
62 import javax.xml.xpath.XPathFactory;
64 import org.apache.commons.io.FilenameUtils;
65 import org.apache.commons.io.IOUtils;
66 import org.onap.policy.common.logging.eelf.MessageCodes;
67 import org.onap.policy.common.logging.eelf.PolicyLogger;
68 import org.onap.policy.common.logging.flexlogger.FlexLogger;
69 import org.onap.policy.common.logging.flexlogger.Logger;
70 import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
71 import org.onap.policy.rest.XACMLRestProperties;
72 import org.onap.policy.rest.adapter.PolicyRestAdapter;
73 import org.onap.policy.rest.dao.PolicyDBException;
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.utils.CryptoUtils;
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 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
92 import com.att.research.xacml.api.pap.PAPException;
93 import com.att.research.xacml.api.pap.PDP;
94 import com.att.research.xacml.api.pap.PDPPolicy;
95 import com.att.research.xacml.util.XACMLProperties;
97 public class PolicyDBDao {
98 private static final Logger logger = FlexLogger.getLogger(PolicyDBDao.class);
99 private List<?> otherServers;
100 private EntityManagerFactory emf;
101 private static PolicyDBDao currentInstance = null;
102 private PAPPolicyEngine papEngine;
104 private static final String JSON_CONFIG = "JSON";
105 private static final String XML_CONFIG = "XML";
106 private static final String PROPERTIES_CONFIG = "PROPERTIES";
107 private static final String OTHER_CONFIG = "OTHER";
109 //Declared to static variables which were repeating multiple times across the PolicyDBDao
110 public static final String config = "Config";
111 public static final String action = "Action";
112 private static final String groupIdVar = "groupId";
113 private static final String deletedVar = "deleted";
114 private static final String groupEntitySelectQuery = "SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted";
115 private static final String pdpEntitySelectQuery = "SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted";
116 private static final String groupCannotBeFound = "The group could not be found with id ";
117 private static final String foundInDBNotDeleted = " were found in the database that are not deleted";
118 private static final String moreThanOnePDP = "Somehow, more than one pdp with the same id ";
119 private static final String deletedStatusFound = " and deleted status were found in the database";
120 private static final String duplicateGroupId = "Somehow, more than one group with the same id ";
121 private static final String pdpIdVariable = "pdpId";
122 private static final String queryFailedToCheckExisting = "Query failed trying to check for existing group";
123 private static final String queryFailedToGetGroup = "Query failed trying to get group ";
124 public static final String scope = "scope";
125 private static final String policyDBDaoVar = "PolicyDBDao";
126 private static final String duplicatePolicyId = "Somehow, more than one policy with the id ";
127 private static final String foundInDB = " were found in the database";
129 private static boolean isJunit = false;
131 public static void setJunit(boolean isJunit) {
132 PolicyDBDao.isJunit = isJunit;
136 * Get an instance of a PolicyDBDao. It creates one if it does not exist.
137 * Only one instance is allowed to be created per server.
138 * @param emf The EntityFactoryManager to be used for database connections
139 * @return The new instance of PolicyDBDao or throw exception if the given emf is null.
140 * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this.
142 public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf){
143 logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called");
144 if(currentInstance == null){
146 currentInstance = new PolicyDBDao(emf);
147 return currentInstance;
149 throw new IllegalStateException("The EntityManagerFactory is Null");
151 return currentInstance;
155 * Gets the current instance of PolicyDBDao.
156 * @return The instance of PolicyDBDao or throws exception if the given instance is null.
157 * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this.
159 public static PolicyDBDao getPolicyDBDaoInstance(){
160 logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called");
161 if(currentInstance != null){
162 return currentInstance;
164 throw new IllegalStateException("The PolicyDBDao.currentInstance is Null. Use getPolicyDBDao(EntityManagerFactory emf)");
167 public void setPapEngine(PAPPolicyEngine papEngine2){
168 this.papEngine = papEngine2;
171 private PolicyDBDao(EntityManagerFactory emf){
172 logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao("+emf+") called");
175 //not needed in this release
177 PolicyLogger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates");
180 otherServers = getRemotePolicyDBDaoList();
181 if(logger.isDebugEnabled()){
182 logger.debug("Number of remote PolicyDBDao instances: "+otherServers.size());
184 if(otherServers.isEmpty()){
185 logger.warn("List of PolicyDBDao servers is empty or could not be retrieved");
189 //not static because we are going to be using the instance's emf
190 //waitTime in ms to wait for lock, or -1 to wait forever (no)
191 private void startTransactionSynced(EntityManager entityMgr,int waitTime){
192 logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as "
193 + "\n startTransactionSynced("+entityMgr+","+waitTime+") called\n\n");
194 DatabaseLockEntity lock = null;
196 entityMgr.setProperty("javax.persistence.query.timeout", waitTime);
197 entityMgr.getTransaction().begin();
199 if(logger.isDebugEnabled()){
200 Map<String,Object> properties = entityMgr.getProperties();
201 logger.debug("\n\nstartTransactionSynced():"
202 + "\n entityManager.getProperties() = " + properties
206 if(logger.isDebugEnabled()){
207 logger.debug("\n\nstartTransactionSynced():"
208 + "\n ATTEMPT to get the DB lock"
211 lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE);
212 if(logger.isDebugEnabled()){
213 logger.debug("\n\nstartTransactionSynced():"
214 + "\n GOT the DB lock"
217 } catch(Exception e){
218 System.out.println("Could not get lock entity");
219 logger.error("Exception Occured"+e);
222 throw new IllegalStateException("The lock row does not exist in the table. Please create a primary key with value = 1.");
227 * Gets the list of other registered PolicyDBDaos from the database
228 * @return List (type PolicyDBDaoEntity) of other PolicyDBDaos
230 private List<?> getRemotePolicyDBDaoList(){
231 logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called");
232 List<?> policyDBDaoEntityList = new LinkedList<>();
233 EntityManager em = emf.createEntityManager();
234 startTransactionSynced(em, 1000);
236 Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll");
237 policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList();
239 } catch(Exception e){
240 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Exception querying for other registered PolicyDBDaos");
241 logger.warn("List of remote PolicyDBDaos will be empty", e);
244 em.getTransaction().commit();
245 } catch(Exception e){
246 logger.warn("List of remote PolicyDBDaos will be empty", e);
248 em.getTransaction().rollback();
249 } catch(Exception e2){
250 logger.debug("List of remote PolicyDBDaos will be empty", e2);
254 return policyDBDaoEntityList;
257 public PolicyDBDaoTransaction getNewTransaction(){
258 logger.debug("getNewTransaction() as getNewTransaction() called");
259 return new PolicyDBDaoTransactionInstance();
263 * Because the normal transactions are not used in audits, we can use the same transaction
264 * mechanism to get a transaction and obtain the emlock and the DB lock. We just need to
265 * provide different transaction timeout values in ms because the audit will run longer
266 * than normal transactions.
268 public PolicyDBDaoTransaction getNewAuditTransaction(){
269 logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called");
270 //Use the standard transaction wait time in ms
271 int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT));
272 //Use the (extended) audit timeout time in ms
273 int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT));
274 return new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs);
279 * Checks if two strings are equal. Null strings ARE allowed.
280 * @param one A String or null to compare
281 * @param two A String or null to compare
283 private static boolean stringEquals(String one, String two){
284 logger.debug("stringEquals(String one, String two) as stringEquals("+one+", "+two+") called");
285 if(one == null && two == null){
288 if(one == null || two == null){
291 return one.equals(two);
295 * Returns the url of this local pap server, removing the username and password, if they are present
296 * @return The url of this local pap server
298 private String[] getPapUrlUserPass(){
299 logger.debug("getPapUrl() as getPapUrl() called");
300 String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
304 return splitPapUrlUserPass(url);
307 private String[] splitPapUrlUserPass(String url){
308 String[] urlUserPass = new String[3];
309 String[] commaSplit = url.split(",");
310 urlUserPass[0] = commaSplit[0];
311 if(commaSplit.length > 2){
312 urlUserPass[1] = commaSplit[1];
313 urlUserPass[2] = commaSplit[2];
315 if(urlUserPass[1] == null || "".equals(urlUserPass[1])){
316 String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
317 if(usernamePropertyValue != null){
318 urlUserPass[1] = usernamePropertyValue;
321 if(urlUserPass[2] == null || "".equals(urlUserPass[2])){
322 String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS);
323 if(passwordPropertyValue != null){
324 urlUserPass[2] = passwordPropertyValue;
327 //if there is no comma, for some reason there is no username and password, so don't try to cut them off
332 * Register the PolicyDBDao instance in the PolicyDBDaoEntity table
333 * @return Boolean, were we able to register?
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){
342 EntityManager em = emf.createEntityManager();
344 startTransactionSynced(em, 1000);
345 } catch(IllegalStateException e){
346 logger.debug ("\nPolicyDBDao.register() caught an IllegalStateException: \n" +e + "\n");
347 DatabaseLockEntity lock;
348 lock = em.find(DatabaseLockEntity.class, 1);
350 lock = new DatabaseLockEntity();
355 em.getTransaction().commit();
357 } catch(Exception e2){
358 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, "COULD NOT CREATE DATABASELOCK ROW. WILL TRY ONE MORE TIME");
361 em = emf.createEntityManager();
363 startTransactionSynced(em, 1000);
364 } catch(Exception e3){
365 String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING";
366 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, policyDBDaoVar, msg);
367 throw new IllegalStateException("msg" + "\n" + e3);
371 logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n");
372 PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]);
373 Query getPolicyDBDaoEntityQuery = em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url");
374 getPolicyDBDaoEntityQuery.setParameter("url", url[0]);
375 // encrypt the password
378 txt = CryptoUtils.encryptTxt(url[2].getBytes(StandardCharsets.UTF_8));
379 } catch(Exception e){
381 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Could not encrypt PAP password");
383 if(foundPolicyDBDaoEntity == null){
384 PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity();
385 em.persist(newPolicyDBDaoEntity);
386 newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]);
387 newPolicyDBDaoEntity.setDescription("PAP server at "+url[0]);
388 newPolicyDBDaoEntity.setUsername(url[1]);
389 newPolicyDBDaoEntity.setPassword(txt);
391 em.getTransaction().commit();
392 } catch(Exception e){
395 em.getTransaction().rollback();
396 } catch(Exception e2){
398 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, "Could not add new PolicyDBDao to the database");
402 //just want to update in order to change modified date
403 if(url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())){
404 foundPolicyDBDaoEntity.setUsername(url[1]);
406 if(txt != null && !stringEquals(txt, foundPolicyDBDaoEntity.getPassword())){
407 foundPolicyDBDaoEntity.setPassword(txt);
409 foundPolicyDBDaoEntity.preUpdate();
411 em.getTransaction().commit();
412 } catch(Exception e){
415 em.getTransaction().rollback();
416 } catch(Exception e2){
418 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, "Could not update PolicyDBDao in the database");
423 logger.debug("\nPolicyDBDao.register(). Success!!\n");
427 private class NotifyOtherThread implements Runnable {
428 public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId){
430 this.entityId = entityId;
431 this.entityType = entityType;
432 this.newGroupId = newGroupId;
435 private long entityId;
436 private String entityType;
437 private String newGroupId;
440 //naming of 'o' is for backwards compatibility with the rest of the function
441 PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity)obj;
442 String o = dbdEntity.getPolicyDBDaoUrl();
443 String username = dbdEntity.getUsername();
446 txt = new String(CryptoUtils.decryptTxt(dbdEntity.getPassword()), StandardCharsets.UTF_8);
447 } catch(Exception e){
449 //if we can't decrypt, might as well try it anyway
450 txt = dbdEntity.getPassword();
452 Base64.Encoder encoder = Base64.getEncoder();
453 String encoding = encoder.encodeToString((username+":"+txt).getBytes(StandardCharsets.UTF_8));
454 HttpURLConnection connection = null;
455 UUID requestID = UUID.randomUUID();
459 String[] papUrlUserPass = getPapUrlUserPass();
460 if(papUrlUserPass == null ){
461 papUrl = "undefined";
463 papUrl = papUrlUserPass[0];
465 logger.debug("We are going to try to notify "+o);
466 //is this our own url?
469 ourUrl = splitPapUrlUserPass((String)o)[0];
476 if(papUrl.equals(ourUrl)){
477 logger.debug(o+" is our url, skipping notify");
480 if(newGroupId == null){
481 url = new URL(o+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType);
483 url = new URL(o+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType+"&extradata="+newGroupId);
485 } catch (MalformedURLException e) {
486 logger.warn("Caught MalformedURLException on: new URL()", e);
490 // Open up the connection
492 logger.info("PolicyDBDao: NotifyOtherThread: notifying other PAPs of an update");
493 logger.info("Connecting with url: "+url);
495 connection = (HttpURLConnection)url.openConnection();
496 } catch (Exception e) {
497 logger.warn("Caught exception on: url.openConnection()",e);
501 // Setup our method and headers
504 connection.setRequestMethod("PUT");
505 } catch (ProtocolException e) {
506 //why would this error ever occur?
507 logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");",e);
510 connection.setRequestProperty("Authorization", "Basic " + encoding);
511 connection.setRequestProperty("Accept", "text/x-java-properties");
512 connection.setRequestProperty("Content-Type", "text/x-java-properties");
513 connection.setRequestProperty("requestID", requestID.toString());
516 readTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT));
517 } catch(Exception e){
518 logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default.", e);
521 connection.setReadTimeout(readTimeout);
522 connection.setConnectTimeout(readTimeout);
523 connection.setUseCaches(false);
525 // Adding this in. It seems the HttpUrlConnection class does NOT
526 // properly forward our headers for POST re-direction. It does so
527 // for a GET re-direction.
529 // So we need to handle this ourselves.
531 connection.setInstanceFollowRedirects(false);
532 connection.setDoOutput(true);
533 connection.setDoInput(true);
535 connection.connect();
536 } catch (Exception e) {
537 logger.warn("Caught exception on: connection.connect()",e);
541 if (connection.getResponseCode() == 200) {
542 logger.info("PolicyDBDao: NotifyOtherThread received response 200 from pap server on notify");
544 logger.warn("PolicyDBDao: NotifyOtherThread connection response code not 200, received: "+connection.getResponseCode());
546 } catch (Exception e) {
547 logger.warn("Caught Exception on: connection.getResponseCode() ", e);
550 connection.disconnect();
554 private static String evaluateXPath(String expression, String xml) {
555 InputSource source = new InputSource(new StringReader(xml));
557 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
558 String description = "";
560 DocumentBuilder db = dbf.newDocumentBuilder();
561 Document document = db.parse(source);
563 XPathFactory xpathFactory = XPathFactory.newInstance();
564 XPath xpath = xpathFactory.newXPath();
566 description = xpath.evaluate(expression, document);
568 logger.error("Exception Occured while evaluating path"+e);
573 private static final String POLICY_NOTIFICATION = "policy";
574 private static final String PDP_NOTIFICATION = "pdp";
575 private static final String GROUP_NOTIFICATION = "group";
576 public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, XACMLPapServlet xacmlPapServlet){
577 logger.info("DBDao url: " + url + " has reported an update on "+entityType+" entity "+entityId);
578 PolicyDBDaoTransaction transaction = this.getNewTransaction();
579 //although its named retries, this is the total number of tries
582 retries = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INCOMINGNOTIFICATION_TRIES));
583 } catch(Exception e){
584 logger.error("xacml.rest.pap.incomingnotification.tries property not set, using a default of 3."+e);
587 //if someone sets it to some dumb value, we need to make sure it will try at least once
591 int pauseBetweenRetries = 1000;
594 case POLICY_NOTIFICATION:
595 for(int i=0; i<retries;i++){
597 handleIncomingPolicyChange(entityId);
599 } catch(Exception e){
601 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")");
604 Thread.sleep(pauseBetweenRetries);
605 }catch(InterruptedException ie){
606 Thread.currentThread().interrupt();
611 case PDP_NOTIFICATION:
612 for(int i=0; i<retries;i++){
614 handleIncomingPdpChange(entityId, transaction);
616 } catch(Exception e){
618 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")");
621 Thread.sleep(pauseBetweenRetries);
622 }catch(InterruptedException ie){
623 Thread.currentThread().interrupt();
628 case GROUP_NOTIFICATION:
629 for(int i=0; i<retries;i++){
631 handleIncomingGroupChange(entityId, extraData, transaction);
635 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")");
638 Thread.sleep(pauseBetweenRetries);
639 }catch(InterruptedException ie){
640 Thread.currentThread().interrupt();
646 //no changes should be being made in this function, we still need to close
647 transaction.rollbackTransaction();
650 private void handleIncomingGroupChange(String groupId, String extraData,PolicyDBDaoTransaction transaction) throws PAPException, PolicyDBException{
651 GroupEntity groupRecord = null;
652 long groupIdLong = -1;
654 groupIdLong = Long.parseLong(groupId);
655 } catch(NumberFormatException e){
656 throw new IllegalArgumentException("groupId "+groupId+" cannot be parsed into a long");
659 groupRecord = transaction.getGroup(groupIdLong);
660 } catch(Exception e){
661 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");");
662 throw new PAPException("Could not get local group "+groupIdLong);
664 if(groupRecord == null){
665 throw new PersistenceException("The group record returned is null");
667 //compare to local fs
668 //does group folder exist
669 OnapPDPGroup localGroup = null;
671 localGroup = papEngine.getGroup(groupRecord.getGroupId());
672 } catch (Exception e) {
673 logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+groupId+");",e);
675 if(localGroup == null && extraData != null){
676 //here we can try to load an old group id from the extraData
678 localGroup = papEngine.getGroup(extraData);
680 logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+extraData+");",e);
683 if(localGroup != null && groupRecord.isDeleted()){
684 OnapPDPGroup newLocalGroup = null;
685 if(extraData != null){
687 newLocalGroup = papEngine.getGroup(extraData);
688 } catch (PAPException e) {
689 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");");
693 papEngine.removeGroup(localGroup, newLocalGroup);
694 } catch (NullPointerException | PAPException e) {
695 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");");
696 throw new PAPException("Could not remove group "+groupId);
699 else if(localGroup == null){
700 //creating a new group
702 papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());
703 } catch (NullPointerException | PAPException e) {
704 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());");
705 throw new PAPException("Could not create group "+groupRecord);
708 localGroup = papEngine.getGroup(groupRecord.getGroupId());
709 } catch (PAPException e1) {
710 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, "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");
713 //add possible pdps to group
714 List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId()));
715 for(Object pdpO : pdpsInGroup){
716 PdpEntity pdp = (PdpEntity)pdpO;
718 papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());
719 } catch (NullPointerException | PAPException e) {
720 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());");
721 throw new PAPException("Could not create pdp "+pdp);
724 //add possible policies to group (filesystem only, apparently)
726 if(!(localGroup instanceof StdPDPGroup)){
727 throw new PAPException("group is not a StdPDPGroup");
730 //because it will be comparing the new group to its own version
731 StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(),localGroup.isDefaultGroup(),localGroup.getName(),localGroup.getDescription(),((StdPDPGroup)localGroup).getDirectory());
732 localGroupClone.setOnapPdps(localGroup.getOnapPdps());
733 localGroupClone.setPipConfigs(localGroup.getPipConfigs());
734 localGroupClone.setStatus(localGroup.getStatus());
735 //we are updating a group or adding a policy or changing default
736 //set default if it should be
737 if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){
739 papEngine.setDefaultGroup(localGroup);
741 } catch (PAPException e) {
742 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");");
743 throw new PAPException("Could not set default group to "+localGroupClone);
746 boolean needToUpdate = false;
747 if(updateGroupPoliciesInFileSystem(localGroupClone,localGroup, groupRecord, transaction)){
750 if(!stringEquals(localGroupClone.getId(),groupRecord.getGroupId()) || !stringEquals(localGroupClone.getName(),groupRecord.getgroupName())){
752 //we do not want to change the id, the papEngine will do this for us, it needs to know the old id
753 localGroupClone.setName(groupRecord.getgroupName());
756 if(!stringEquals(localGroupClone.getDescription(),groupRecord.getDescription())){
757 localGroupClone.setDescription(groupRecord.getDescription());
762 papEngine.updateGroup(localGroupClone);
763 } catch (PAPException e) {
764 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");");
765 throw new PAPException("Could not update group "+localGroupClone);
771 //this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db
772 private boolean updateGroupPoliciesInFileSystem(OnapPDPGroup pdpGroup,OnapPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException, PolicyDBException{
773 if(!(pdpGroup instanceof StdPDPGroup)){
774 throw new PAPException("group is not a StdPDPGroup");
776 StdPDPGroup group = (StdPDPGroup)pdpGroup;
777 //this must always be true since we don't explicitly know when a delete is occuring
778 boolean didUpdate = true;
779 HashMap<String,PDPPolicy> currentPolicySet = new HashMap<>(oldPdpGroup.getPolicies().size());
780 HashSet<PDPPolicy> newPolicySet = new HashSet<>();
781 for(PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()){
782 currentPolicySet.put(pdpPolicy.getId(), pdpPolicy);
784 for(PolicyEntity policy : groupRecord.getPolicies()){
785 String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
786 if(group.getPolicy(pdpPolicyName) == null){
788 if(currentPolicySet.containsKey(pdpPolicyName)){
789 newPolicySet.add(currentPolicySet.get(pdpPolicyName));
791 logger.info("PolicyDBDao: Adding the new policy to the PDP group after notification: " + pdpPolicyName);
792 InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
793 group.copyPolicyToFile(pdpPolicyName,policyStream);
794 ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(pdpPolicyName));
796 policyStream.close();
797 } catch (IOException e) {
799 PolicyLogger.error(e.getMessage() +e);
804 logger.info("PolicyDBDao: Adding updated policies to group after notification.");
806 newPolicySet.addAll(group.getPolicies());
807 group.setPolicies(newPolicySet);
813 * This method is called during all pushPolicy transactions and makes sure the file system
814 * group is in sync with the database groupentity
816 private StdPDPGroup synchronizeGroupPoliciesInFileSystem(StdPDPGroup pdpGroup, GroupEntity groupentity) throws PAPException, PolicyDBException{
818 HashMap<String,PDPPolicy> currentPolicyMap = new HashMap<>();
819 HashSet<String> newPolicyIdSet = new HashSet<>();
820 HashSet<PDPPolicy> newPolicySet = new HashSet<>();
822 for(PDPPolicy pdpPolicy : pdpGroup.getPolicies()){
823 currentPolicyMap.put(pdpPolicy.getId(), pdpPolicy);
826 for(PolicyEntity policy : groupentity.getPolicies()){
827 String pdpPolicyId = getPdpPolicyName(policy.getPolicyName(), policy.getScope());
828 newPolicyIdSet.add(pdpPolicyId);
830 if(currentPolicyMap.containsKey(pdpPolicyId)){
831 newPolicySet.add(currentPolicyMap.get(pdpPolicyId));
833 //convert PolicyEntity object to PDPPolicy
834 String name = pdpPolicyId.replace(".xml", "");
835 name = name.substring(0, name.lastIndexOf('.'));
836 InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes());
837 pdpGroup.copyPolicyToFile(pdpPolicyId,name,policyStream);
838 URI location = Paths.get(pdpGroup.getDirectory().toAbsolutePath().toString(), pdpPolicyId).toUri();
839 StdPDPPolicy newPolicy = null;
841 newPolicy = new StdPDPPolicy(pdpPolicyId, true, removeExtensionAndVersionFromPolicyName(pdpPolicyId),location);
842 newPolicySet.add(newPolicy);
843 } catch (Exception e) {
845 PolicyLogger.error("PolicyDBDao: Exception occurred while creating the StdPDPPolicy newPolicy object " + e.getMessage());
850 for(String id : currentPolicyMap.keySet()) {
851 if(!newPolicyIdSet.contains(id)){
853 Files.delete(Paths.get(currentPolicyMap.get(id).getLocation()));
854 } catch (Exception e) {
856 PolicyLogger.error("PolicyDBDao: Exception occurred while attempting to delete the old version of the policy file from the group. " + e.getMessage());
861 logger.info("PolicyDBDao: Adding new policy set to group to keep filesystem and DB in sync");
862 pdpGroup.setPolicies(newPolicySet);
867 private String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException{
868 return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0];
872 * Splits apart the policy name and version from a policy file path
873 * @param originalPolicyName: a policy file name ex: Config_policy.2.xml
874 * @return An array [0]: The policy name, [1]: the policy version, as a string
876 private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException{
877 String policyName = originalPolicyName;
878 String[] nameAndVersion = new String[2];
880 policyName = removeFileExtension(policyName);
881 nameAndVersion[0] = policyName.substring(0,policyName.lastIndexOf('.'));
882 if(isNullOrEmpty(nameAndVersion[0])){
883 throw new PolicyDBException();
885 } catch(Exception e){
886 nameAndVersion[0] = originalPolicyName;
890 nameAndVersion[1] = policyName.substring(policyName.lastIndexOf('.')+1);
891 if(isNullOrEmpty(nameAndVersion[1])){
892 throw new PolicyDBException();
894 } catch(Exception e){
895 nameAndVersion[1] = "1";
898 return nameAndVersion;
901 private void handleIncomingPdpChange(String pdpId, PolicyDBDaoTransaction transaction) throws PAPException{
905 pdpIdLong = Long.parseLong(pdpId);
906 }catch(NumberFormatException e){
907 throw new IllegalArgumentException("pdpId "+pdpId+" cannot be parsed into a long");
909 PdpEntity pdpRecord = null;
911 pdpRecord = transaction.getPdp(pdpIdLong);
913 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");");
914 throw new PAPException("Could not get local pdp "+pdpIdLong);
916 if(pdpRecord == null){
917 throw new PersistenceException("The pdpRecord returned is null");
921 localPdp = papEngine.getPDP(pdpRecord.getPdpId());
922 } catch (PAPException e) {
923 logger.warn("Caught PAPException trying to get local pdp with papEngine.getPDP("+pdpId+");",e);
925 if(localPdp != null && pdpRecord.isDeleted()){
927 papEngine.removePDP((OnapPDP) localPdp);
928 } catch (PAPException e) {
929 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");");
930 throw new PAPException("Could not remove pdp "+pdpId);
933 else if(localPdp == null){
936 OnapPDPGroup localGroup = null;
938 localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
939 } catch (PAPException e1) {
940 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
941 throw new PAPException("Could not get local group");
944 papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort());
945 } catch (NullPointerException | PAPException e) {
946 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to create pdp with papEngine.newPDP("+pdpRecord.getPdpId()+", "+localGroup+", "+pdpRecord.getPdpName()+", "+pdpRecord.getDescription()+", "+pdpRecord.getJmxPort()+");");
947 throw new PAPException("Could not create pdp "+pdpRecord);
950 boolean needToUpdate = false;
951 if(!stringEquals(localPdp.getId(),pdpRecord.getPdpId()) || !stringEquals(localPdp.getName(),pdpRecord.getPdpName())){
952 //again, we don't want to change the id, the papEngine will do this
953 localPdp.setName(pdpRecord.getPdpName());
956 if(!stringEquals(localPdp.getDescription(),pdpRecord.getDescription())){
957 localPdp.setDescription(pdpRecord.getDescription());
960 String localPdpGroupId = null;
962 localPdpGroupId = papEngine.getPDPGroup((OnapPDP) localPdp).getId();
963 } catch(PAPException e){
964 //could be null or something, just warn at this point
965 logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();",e);
967 if(!stringEquals(localPdpGroupId,pdpRecord.getGroup().getGroupId())){
968 OnapPDPGroup newPdpGroup = null;
970 newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId());
971 }catch(PAPException e){
972 //ok, now we have an issue. Time to stop things
973 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());");
974 throw new PAPException("Could not get local group");
977 papEngine.movePDP((OnapPDP) localPdp, newPdpGroup);
978 }catch(PAPException e){
979 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);");
980 throw new PAPException("Could not move pdp "+localPdp);
983 if(((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()){
984 ((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort());
989 papEngine.updatePDP((OnapPDP) localPdp);
990 } catch (PAPException e) {
991 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");");
992 throw new PAPException("Could not update pdp "+localPdp);
996 //compare to local situation
997 //call command to update
999 private void handleIncomingPolicyChange(String policyId){
1000 String policyName = null;
1001 EntityManager em = emf.createEntityManager();
1002 Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById");
1003 getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId));
1005 @SuppressWarnings("unchecked")
1006 List<PolicyEntity> policies = getPolicyEntityQuery.getResultList();
1007 PolicyEntity policy = null;
1008 if (!policies.isEmpty()){
1009 policy = policies.get(0);
1011 String action = "unknown action";
1014 policyName = policy.getPolicyName();
1015 logger.info("Deleting old Policy Config File for " + policy.getPolicyName());
1017 Path subFile = null;
1019 if (policy.getConfigurationData()!= null){
1020 subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), config);
1021 }else if(policy.getActionBodyEntity()!= null){
1022 subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), action);
1025 if(subFile != null){
1026 Files.deleteIfExists(subFile);
1028 if (policy.getConfigurationData()!= null){
1029 writePolicySubFile(policy, config);
1030 }else if(policy.getActionBodyEntity()!= null){
1031 writePolicySubFile(policy, action);
1034 } catch (IOException e1) {
1035 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, "Error occurred while performing [" + action + "] of Policy File: " + policyName);
1039 private String getPdpPolicyName(String name, String scope){
1040 String finalName = "";
1043 finalName += removeFileExtension(name);
1044 finalName += ".xml";
1047 private String removeFileExtension(String fileName){
1048 return fileName.substring(0, fileName.lastIndexOf('.'));
1051 private Path getPolicySubFile(String inputFileName, String subFileType){
1052 String filename = inputFileName;
1053 logger.info("getPolicySubFile(" + filename + ", " + subFileType + ")");
1054 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS), subFileType);
1057 filename = FilenameUtils.removeExtension(filename);
1059 for(File tmpFile : filePath.toFile().listFiles()){
1060 if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)){
1065 Path finalPath = null;
1067 finalPath = Paths.get(file.getAbsolutePath());
1070 logger.info("end of getPolicySubFile: " + finalPath);
1074 private boolean writePolicySubFile(PolicyEntity policy, String policyType){
1075 logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + "]");
1077 String subTypeName = null;
1078 String subTypeBody = null;
1079 if (config.equalsIgnoreCase(policyType)){
1081 subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName());
1082 subTypeBody = policy.getConfigurationData().getConfigBody();
1084 String configType = policy.getConfigurationData().getConfigType();
1086 if (configType != null) {
1087 if (configType.equals(JSON_CONFIG)) {
1088 subTypeName = subTypeName + ".json";
1090 if (configType.equals(XML_CONFIG)) {
1091 subTypeName = subTypeName + ".xml";
1093 if (configType.equals(PROPERTIES_CONFIG)) {
1094 subTypeName = subTypeName + ".properties";
1096 if (configType.equals(OTHER_CONFIG)) {
1097 subTypeName = subTypeName + ".txt";
1100 }else if (action.equalsIgnoreCase(policyType)){
1102 subTypeName = policy.getActionBodyEntity().getActionBodyName();
1103 subTypeBody = policy.getActionBodyEntity().getActionBody();
1105 Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type);
1107 if(subTypeBody == null){
1110 boolean success = false;
1112 Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName));
1113 File file = Paths.get(filePath.toString(),subTypeName).toFile();
1114 boolean value = file.createNewFile();
1115 logger.debug("New file created successfully"+value);
1116 try(FileWriter fileWriter = new FileWriter(file, false)){
1117 // false to overwrite
1118 fileWriter.write(subTypeBody);
1122 } catch (Exception e) {
1123 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName());
1128 public void auditLocalDatabase(PAPPolicyEngine papEngine2){
1129 logger.debug("PolicyDBDao.auditLocalDatabase() is called");
1131 deleteAllGroupTables();
1132 auditGroups(papEngine2);
1133 } catch(Exception e){
1134 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "auditLocalDatabase() error");
1135 logger.error("Exception Occured"+e);
1140 public StdPDPGroup auditLocalFileSystem(StdPDPGroup group){
1142 logger.info("Starting Local File System group audit");
1143 EntityManager em = emf.createEntityManager();
1144 em.getTransaction().begin();
1146 StdPDPGroup updatedGroup = null;
1148 Query groupQuery = em.createQuery(groupEntitySelectQuery);
1149 groupQuery.setParameter(groupIdVar, group.getId());
1150 groupQuery.setParameter(deletedVar, false);
1151 List<?> groupQueryList = groupQuery.getResultList();
1152 if(groupQueryList!=null && !groupQueryList.isEmpty()){
1153 GroupEntity dbgroup = (GroupEntity)groupQueryList.get(0);
1154 updatedGroup = synchronizeGroupPoliciesInFileSystem(group, dbgroup);
1155 logger.info("Group was updated during file system audit: " + updatedGroup.toString());
1157 } catch (PAPException | PolicyDBException e) {
1159 } catch (Exception e) {
1161 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if group exists groupQuery.getResultList()");
1162 throw new PersistenceException("Query failed trying to check if group "+group.getId()+" exists");
1165 em.getTransaction().commit();
1168 return updatedGroup;
1172 public void deleteAllGroupTables(){
1173 logger.debug("PolicyDBDao.deleteAllGroupTables() called");
1174 EntityManager em = emf.createEntityManager();
1175 em.getTransaction().begin();
1177 Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll");
1178 deletePdpEntityEntityTableUpdate.executeUpdate();
1180 Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll");
1181 deleteGroupEntityTableUpdate.executeUpdate();
1183 em.getTransaction().commit();
1187 @SuppressWarnings("unchecked")
1188 public void auditGroups(PAPPolicyEngine papEngine2){
1189 logger.debug("PolicyDBDao.auditGroups() called");
1191 EntityManager em = emf.createEntityManager();
1192 em.getTransaction().begin();
1193 final String AUDIT_STR = "Audit";
1196 Set<OnapPDPGroup> groups = papEngine2.getOnapPDPGroups();
1198 for (OnapPDPGroup grp : groups){
1200 GroupEntity groupEntity = new GroupEntity();
1201 em.persist(groupEntity);
1202 groupEntity.setGroupName(grp.getName());
1203 groupEntity.setDescription(grp.getDescription());
1204 groupEntity.setDefaultGroup(grp.isDefaultGroup());
1205 groupEntity.setCreatedBy(AUDIT_STR);
1206 groupEntity.setGroupId(createNewPDPGroupId(grp.getId()));
1207 groupEntity.setModifiedBy(AUDIT_STR);
1208 Set<OnapPDP> pdps = grp.getOnapPdps();
1210 for(OnapPDP pdp : pdps){
1211 PdpEntity pdpEntity = new PdpEntity();
1212 em.persist(pdpEntity);
1213 pdpEntity.setGroup(groupEntity);
1214 pdpEntity.setJmxPort(pdp.getJmxPort());
1215 pdpEntity.setPdpId(pdp.getId());
1216 pdpEntity.setPdpName(pdp.getName());
1217 pdpEntity.setModifiedBy(AUDIT_STR);
1218 pdpEntity.setCreatedBy(AUDIT_STR);
1222 Set<PDPPolicy> policies = grp.getPolicies();
1224 for(PDPPolicy policy : policies){
1226 String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId());
1227 if(stringArray == null) {
1228 throw new IllegalArgumentException("Invalid input - policyID must contain name, scope and version");
1230 List<PolicyEntity> policyEntityList;
1231 Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope");
1232 getPolicyEntitiesQuery.setParameter("name", stringArray[0]);
1233 getPolicyEntitiesQuery.setParameter(scope, stringArray[1]);
1235 policyEntityList = getPolicyEntitiesQuery.getResultList();
1236 PolicyEntity policyEntity = null;
1237 if(!policyEntityList.isEmpty()){
1238 policyEntity = policyEntityList.get(0);
1240 if(policyEntity != null){
1241 groupEntity.addPolicyToGroup(policyEntity);
1243 }catch(Exception e2){
1244 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, "Exception auditGroups inner catch");
1247 }catch(Exception e1){
1248 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, "Exception auditGroups middle catch");
1251 }catch(Exception e){
1252 em.getTransaction().rollback();
1253 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Exception auditGroups outer catch");
1258 em.getTransaction().commit();
1263 private String getConfigFile(String filename, PolicyRestAdapter policy){
1265 return getConfigFile(filename, (String)null);
1267 return getConfigFile(filename, policy.getConfigType());
1269 //copied from ConfigPolicy.java and modified
1270 // Here we are adding the extension for the configurations file based on the
1271 // config type selection for saving.
1272 private String getConfigFile(String inputFilename, String configType) {
1273 String filename = inputFilename;
1274 logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile("+filename+", "+configType+") called");
1275 filename = FilenameUtils.removeExtension(filename);
1276 String id = configType;
1279 if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) {
1280 filename = filename + ".json";
1282 if (id.equals(ConfigPolicy.XML_CONFIG)) {
1283 filename = filename + ".xml";
1285 if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) {
1286 filename = filename + ".properties";
1288 if (id.equals(ConfigPolicy.OTHER_CONFIG)) {
1289 filename = filename + ".txt";
1295 private String[] getNameScopeAndVersionFromPdpPolicy(String fileName){
1296 String[] splitByDots = fileName.split("\\.");
1297 if(splitByDots.length < 3){
1300 String policyName = splitByDots[splitByDots.length-3];
1301 String version = splitByDots[splitByDots.length-2];
1302 //policy names now include version
1304 for(int i=0;i<splitByDots.length-3;i++){
1305 scope += ".".concat(splitByDots[i]);
1307 //remove the first dot
1308 if(scope.length() > 0){
1309 scope = scope.substring(1);
1311 String[] returnArray = new String[3];
1312 returnArray[0] = policyName + "." + version + ".xml";
1313 returnArray[2] = version;
1314 returnArray[1] = scope;
1318 public static String createNewPDPGroupId(String name) {
1320 // replace "bad" characters with sequences that will be ok for file names and properties keys.
1321 id = id.replace(" ", "_sp_");
1322 id = id.replace("\t", "_tab_");
1323 id = id.replace("\\", "_bksl_");
1324 id = id.replace("/", "_sl_");
1325 id = id.replace(":", "_col_");
1326 id = id.replace("*", "_ast_");
1327 id = id.replace("?", "_q_");
1328 id = id.replace("\"", "_quo_");
1329 id = id.replace("<", "_lt_");
1330 id = id.replace(">", "_gt_");
1331 id = id.replace("|", "_bar_");
1332 id = id.replace("=", "_eq_");
1333 id = id.replace(",", "_com_");
1334 id = id.replace(";", "_scom_");
1340 * Checks if any of the given strings are empty or null
1341 * @param strings One or more Strings (or nulls) to check if they are null or empty
1342 * @return true if one or more of the given strings are empty or null
1344 public static boolean isNullOrEmpty(String... strings){
1345 for(String s : strings){
1346 if(s == null || "".equals(s)){
1354 private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction {
1355 private EntityManager em;
1356 private final Object emLock = new Object();
1361 private boolean operationRun = false;
1362 private final Thread transactionTimer;
1364 private PolicyDBDaoTransactionInstance(){
1365 //call the constructor with arguments
1366 this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)),
1367 Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)));
1369 //timeout is how long the transaction can sit before rolling back
1370 //wait time is how long to wait for the transaction to start before throwing an exception
1371 private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime){
1372 if(logger.isDebugEnabled()){
1373 logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:"
1374 + "\n transactionTimeout = " + transactionTimeout
1375 + "\n transactionWaitTime = " + transactionWaitTime + "\n\n");
1377 this.em = emf.createEntityManager();
1382 synchronized(emLock){
1384 startTransactionSynced(this.em,transactionWaitTime);
1385 } catch(Exception e){
1387 throw new PersistenceException("Could not lock transaction within "+transactionWaitTime+" milliseconds");
1390 class TransactionTimer implements Runnable {
1392 private int sleepTime;
1393 public TransactionTimer(int timeout){
1394 this.sleepTime = timeout;
1398 if(logger.isDebugEnabled()){
1399 Date date= new java.util.Date();
1400 logger.debug("\n\nTransactionTimer.run() - SLEEPING: "
1401 + "\n sleepTime (ms) = " + sleepTime
1402 + "\n TimeStamp = " + date.getTime()
1406 Thread.sleep(sleepTime);
1407 } catch (InterruptedException e) {
1408 //probably, the transaction was completed, the last thing we want to do is roll back
1409 if(logger.isDebugEnabled()){
1410 Date date= new java.util.Date();
1411 logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: "
1412 + "\n TimeStamp = " + date.getTime()
1415 Thread.currentThread().interrupt();
1418 if(logger.isDebugEnabled()){
1419 Date date= new java.util.Date();
1420 logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: "
1421 + "\n TimeStamp = " + date.getTime()
1424 rollbackTransaction();
1429 transactionTimer = new Thread(new TransactionTimer(transactionTimeout),"transactionTimerThread");
1430 transactionTimer.start();
1435 private void checkBeforeOperationRun(){
1436 checkBeforeOperationRun(false);
1438 private void checkBeforeOperationRun(boolean justCheckOpen){
1439 if(!isTransactionOpen()){
1440 PolicyLogger.error("There is no transaction currently open");
1441 throw new IllegalStateException("There is no transaction currently open");
1443 if(operationRun && !justCheckOpen){
1444 PolicyLogger.error("An operation has already been performed and the current transaction should be committed");
1445 throw new IllegalStateException("An operation has already been performed and the current transaction should be committed");
1447 operationRun = true;
1450 public void commitTransaction() {
1451 synchronized(emLock){
1452 logger.debug("commitTransaction() as commitTransaction() called");
1453 if(!isTransactionOpen()){
1454 logger.warn("There is no open transaction to commit");
1457 } catch(Exception e){
1458 logger.error("Exception Occured"+e);
1463 em.getTransaction().commit();
1464 } catch(RollbackException e){
1465 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught RollbackException on em.getTransaction().commit()");
1466 throw new PersistenceException("The commit failed. Message:\n"+e.getMessage());
1471 if(newGroupId != null){
1473 notifyOthers(policyId,POLICY_NOTIFICATION,newGroupId);
1474 } catch(Exception e){
1475 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")");
1479 notifyOthers(policyId,POLICY_NOTIFICATION);
1480 } catch(Exception e){
1481 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")");
1486 //we don't want commit to fail just because this does
1487 if(newGroupId != null){
1489 notifyOthers(groupId,GROUP_NOTIFICATION,newGroupId);
1490 } catch(Exception e){
1491 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")");
1495 notifyOthers(groupId,GROUP_NOTIFICATION);
1496 } catch(Exception e){
1497 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")");
1502 //we don't want commit to fail just because this does
1504 notifyOthers(pdpId,PDP_NOTIFICATION);
1505 } catch(Exception e){
1506 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")");
1510 if(transactionTimer != null){
1511 transactionTimer.interrupt();
1516 public void rollbackTransaction() {
1517 logger.debug("rollbackTransaction() as rollbackTransaction() called");
1518 synchronized(emLock){
1519 if(isTransactionOpen()){
1522 em.getTransaction().rollback();
1523 } catch(Exception e){
1524 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Could not rollback transaction");
1528 }catch(Exception e){
1529 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Could not close EntityManager");
1535 }catch(Exception e){
1536 logger.warn("Could not close already closed transaction", e);
1541 if(transactionTimer != null){
1542 transactionTimer.interrupt();
1546 private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String inputPolicyName, String policyDataString) {
1547 String policyName = inputPolicyName;
1548 logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) as createPolicy("+policy+", "+username+", "+policyScope+", "+policyName+", "+policyDataString+") called");
1549 synchronized(emLock){
1550 checkBeforeOperationRun();
1551 String configName = policyName;
1552 if(policyName.contains("Config_")){
1553 policyName = policyName.replace(".Config_", ":Config_");
1554 }else if(policyName.contains("Action_")){
1555 policyName = policyName.replace(".Action_", ":Action_");
1556 }else if(policyName.contains("Decision_")){
1557 policyName = policyName.replace(".Decision_", ":Decision_");
1559 policyName = policyName.split(":")[1];
1560 Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName");
1561 createPolicyQuery.setParameter(scope, policyScope);
1562 createPolicyQuery.setParameter("policyName", policyName);
1563 List<?> createPolicyQueryList = createPolicyQuery.getResultList();
1564 PolicyEntity newPolicyEntity;
1566 if(createPolicyQueryList.isEmpty()){
1567 newPolicyEntity = new PolicyEntity();
1569 } else if(createPolicyQueryList.size() > 1){
1570 PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1571 throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database");
1573 newPolicyEntity = (PolicyEntity)createPolicyQueryList.get(0);
1577 ActionBodyEntity newActionBodyEntity = null;
1578 if(policy.getPolicyType().equals(action)){
1579 boolean abupdate = false;
1580 if(newPolicyEntity.getActionBodyEntity() == null){
1581 newActionBodyEntity = new ActionBodyEntity();
1583 newActionBodyEntity = em.find(ActionBodyEntity.class, newPolicyEntity.getActionBodyEntity().getActionBodyId());
1587 if(newActionBodyEntity != null){
1589 em.persist(newActionBodyEntity);
1591 //build the file path
1592 //trim the .xml off the end
1593 String policyNameClean = FilenameUtils.removeExtension(configName);
1594 String actionBodyName = policyNameClean + ".json";
1596 //get the action body
1597 String actionBodyString = policy.getActionBody();
1598 if(actionBodyString == null){
1599 actionBodyString = "{}";
1601 newActionBodyEntity.setActionBody(actionBodyString);
1602 newActionBodyEntity.setActionBodyName(actionBodyName);
1603 newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()");
1604 newActionBodyEntity.setDeleted(false);
1606 newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()");
1608 if(logger.isDebugEnabled()){
1609 logger.debug("\nPolicyDBDao.createPolicy"
1610 + "\n newActionBodyEntity.getActionBody() = " + newActionBodyEntity.getActionBody()
1611 + "\n newActionBodyEntity.getActionBodyName() = " + newActionBodyEntity.getActionBodyName()
1612 + "\n newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy()
1613 + "\n newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy()
1614 + "\n newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted()
1615 + "\n FLUSHING to DB");
1617 //push the actionBodyEntity to the DB
1620 //newActionBodyEntity == null
1621 //We have a actionBody in the policy but we found no actionBody in the DB
1622 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an "
1623 + "actionBody, but it could not be found in the DB for update."
1624 + "\n policyScope = " + policyScope
1625 + "\n policyName = " + policyName + "\n\n";
1626 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it could not be found in the DB for update: policyName = " + policyName);
1627 throw new IllegalArgumentException(msg);
1631 ConfigurationDataEntity newConfigurationDataEntity;
1632 if(policy.getPolicyType().equals(config)){
1633 boolean configUpdate;
1634 if(newPolicyEntity.getConfigurationData() == null){
1635 newConfigurationDataEntity = new ConfigurationDataEntity();
1636 configUpdate = false;
1638 newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, newPolicyEntity.getConfigurationData().getConfigurationDataId());
1639 configUpdate = true;
1642 if(newConfigurationDataEntity != null){
1644 em.persist(newConfigurationDataEntity);
1646 if(!stringEquals(newConfigurationDataEntity.getConfigurationName(),getConfigFile(configName,policy))){
1647 newConfigurationDataEntity.setConfigurationName(getConfigFile(configName,policy));
1649 if(newConfigurationDataEntity.getConfigType() == null || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())){
1650 newConfigurationDataEntity.setConfigType(policy.getConfigType());
1653 newConfigurationDataEntity.setCreatedBy(username);
1655 if(newConfigurationDataEntity.getModifiedBy() == null || !newConfigurationDataEntity.getModifiedBy().equals(username)){
1656 newConfigurationDataEntity.setModifiedBy(username);
1658 if(newConfigurationDataEntity.getDescription() == null || !newConfigurationDataEntity.getDescription().equals("")){
1659 newConfigurationDataEntity.setDescription("");
1661 if(newConfigurationDataEntity.getConfigBody() == null || newConfigurationDataEntity.getConfigBody().isEmpty() ||
1662 (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))){
1663 //hopefully one of these won't be null
1664 if(policy.getConfigBodyData() == null || policy.getConfigBodyData().isEmpty()){
1665 newConfigurationDataEntity.setConfigBody(policy.getJsonBody());
1667 newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData());
1670 if(newConfigurationDataEntity.isDeleted()){
1671 newConfigurationDataEntity.setDeleted(false);
1676 //We have a configurationData body in the policy but we found no configurationData body in the DB
1677 String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a "
1678 + "configurationData body, but it could not be found in the DB for update."
1679 + "\n policyScope = " + policyScope
1680 + "\n policyName = " + policyName + "\n\n";
1681 PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, but it could not be found in the DB for update: policyName = " + policyName);
1682 throw new IllegalArgumentException(msg);
1686 newConfigurationDataEntity = null;
1689 em.persist(newPolicyEntity);
1692 policyId = newPolicyEntity.getPolicyId();
1694 if(!stringEquals(newPolicyEntity.getPolicyName(),policyName)){
1695 newPolicyEntity.setPolicyName(policyName);
1697 if(!stringEquals(newPolicyEntity.getCreatedBy(),username)){
1698 newPolicyEntity.setCreatedBy(username);
1700 if(!stringEquals(newPolicyEntity.getDescription(),policy.getPolicyDescription())){
1701 newPolicyEntity.setDescription(policy.getPolicyDescription());
1703 if(!stringEquals(newPolicyEntity.getModifiedBy(),username)){
1704 newPolicyEntity.setModifiedBy(username);
1706 if(!stringEquals(newPolicyEntity.getPolicyData(),policyDataString)){
1707 newPolicyEntity.setPolicyData(policyDataString);
1709 if(!stringEquals(newPolicyEntity.getScope(),policyScope)){
1710 newPolicyEntity.setScope(policyScope);
1712 if(newPolicyEntity.isDeleted() == true){
1713 newPolicyEntity.setDeleted(false);
1715 newPolicyEntity.setConfigurationData(newConfigurationDataEntity);
1716 newPolicyEntity.setActionBodyEntity(newActionBodyEntity);
1719 this.policyId = newPolicyEntity.getPolicyId();
1724 @SuppressWarnings("unused")
1725 public PolicyEntity getPolicy(int policyID){
1726 return getPolicy(policyID,null,null);
1728 public PolicyEntity getPolicy(String policyName,String scope){
1729 return getPolicy(-1,policyName,scope);
1731 private PolicyEntity getPolicy(int policyID, String policyName,String scope){
1732 logger.debug("getPolicy(int policyId, String policyName) as getPolicy("+policyID+","+policyName+") called");
1733 if(policyID < 0 && isNullOrEmpty(policyName,scope)){
1734 throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank");
1737 synchronized(emLock){
1738 checkBeforeOperationRun(true);
1739 //check if group exists
1742 if(!isNullOrEmpty(policyName,scope)){
1743 policyId = policyName;
1744 policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope");
1745 policyQuery.setParameter("name", policyId);
1746 policyQuery.setParameter("scope", scope);
1748 policyId = String.valueOf(policyID);
1749 policyQuery = em.createNamedQuery("PolicyEntity.FindById");
1750 policyQuery.setParameter("id", policyId);
1752 List<?> policyQueryList;
1754 policyQueryList = policyQuery.getResultList();
1755 }catch(Exception e){
1756 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get policy with policyQuery.getResultList()");
1757 throw new PersistenceException("Query failed trying to get policy "+policyId);
1759 if(policyQueryList.isEmpty()){
1760 PolicyLogger.error("Policy does not exist with id "+policyId);
1761 throw new PersistenceException("Group policy is being added to does not exist with id "+policyId);
1762 } else if(policyQueryList.size() > 1){
1763 PolicyLogger.error(duplicatePolicyId+policyId+foundInDB);
1764 throw new PersistenceException(duplicatePolicyId+policyId+foundInDB);
1766 return (PolicyEntity)policyQueryList.get(0);
1771 public GroupEntity getGroup(long groupKey){
1772 logger.debug("getGroup(int groupKey) as getGroup("+groupKey+") called");
1774 throw new IllegalArgumentException("groupKey must be at least 0");
1776 synchronized(emLock){
1777 checkBeforeOperationRun(true);
1778 //check if group exists
1779 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey");
1780 groupQuery.setParameter("groupKey", groupKey);
1781 List<?> groupQueryList;
1783 groupQueryList = groupQuery.getResultList();
1784 }catch(Exception e){
1785 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get group with groupQuery.getResultList()");
1786 throw new PersistenceException(queryFailedToGetGroup+groupKey);
1788 if(groupQueryList.isEmpty()){
1789 PolicyLogger.error("Group does not exist with groupKey "+groupKey);
1790 throw new PersistenceException("Group does not exist with groupKey "+groupKey);
1791 } else if(groupQueryList.size() > 1){
1792 PolicyLogger.error("Somehow, more than one group with the groupKey "+groupKey+foundInDB);
1793 throw new PersistenceException("Somehow, more than one group with the groupKey "+groupKey+foundInDB);
1795 return (GroupEntity)groupQueryList.get(0);
1800 public GroupEntity getGroup(String groupId){
1801 logger.debug("getGroup(String groupId) as getGroup("+groupId+") called");
1802 if(isNullOrEmpty(groupId)){
1803 throw new IllegalArgumentException("groupId must not be null or empty");
1805 synchronized(emLock){
1806 checkBeforeOperationRun(true);
1807 //check if group exists
1808 Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId");
1809 groupQuery.setParameter(groupIdVar, groupId);
1810 List<?> groupQueryList;
1812 groupQueryList = groupQuery.getResultList();
1813 }catch(Exception e){
1814 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get group with groupQuery.getResultList()");
1815 throw new PersistenceException(queryFailedToGetGroup+groupId);
1817 if(groupQueryList.isEmpty()){
1818 PolicyLogger.error("Group does not exist with id "+groupId);
1819 throw new PersistenceException("Group does not exist with id "+groupId);
1820 } else if(groupQueryList.size() > 1){
1821 PolicyLogger.error(duplicateGroupId +groupId+foundInDB);
1822 throw new PersistenceException(duplicateGroupId+groupId+foundInDB);
1824 return (GroupEntity)groupQueryList.get(0);
1829 public List<?> getPdpsInGroup(long groupKey){
1830 logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup("+groupKey+") called");
1832 throw new IllegalArgumentException("groupId must not be < 0");
1834 synchronized(emLock){
1835 checkBeforeOperationRun(true);
1836 Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group");
1837 pdpsQuery.setParameter("group", getGroup(groupKey));
1838 return pdpsQuery.getResultList();
1843 public PdpEntity getPdp(long pdpKey){
1844 logger.debug("getPdp(int pdpKey) as getPdp("+pdpKey+") called");
1846 throw new IllegalArgumentException("pdpKey must be at least 0");
1848 synchronized(emLock){
1849 checkBeforeOperationRun(true);
1850 //check if group exists
1851 Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey");
1852 pdpQuery.setParameter("pdpKey", pdpKey);
1853 List<?> pdpQueryList;
1855 pdpQueryList = pdpQuery.getResultList();
1856 }catch(Exception e){
1857 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get pdp with pdpQuery.getResultList()");
1858 throw new PersistenceException("Query failed trying to get pdp "+pdpKey);
1860 if(pdpQueryList.isEmpty()){
1861 PolicyLogger.error("Pdp does not exist with pdpKey "+pdpKey);
1862 throw new PersistenceException("Pdp does not exist with pdpKey "+pdpKey);
1863 } else if(pdpQueryList.size() > 1){
1864 PolicyLogger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+foundInDB);
1865 throw new PersistenceException("Somehow, more than one pdp with the pdpKey "+pdpKey+foundInDB);
1867 return (PdpEntity)pdpQueryList.get(0);
1872 public boolean isTransactionOpen() {
1873 logger.debug("isTransactionOpen() as isTransactionOpen() called");
1874 synchronized(emLock){
1875 return em.isOpen() && em.getTransaction().isActive();
1879 private String processConfigPath(String inputConfigPath){
1880 String configPath = inputConfigPath;
1881 String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS);
1882 if(webappsPath == null){
1883 logger.error("Webapps property does not exist");
1884 throw new IllegalArgumentException("Webapps property does not exist");
1886 configPath = configPath.replace("$URL", webappsPath);
1887 //make sure the correct slashes are in
1889 configPath = Paths.get(configPath).toString();
1890 } catch(InvalidPathException e){
1891 logger.error("Invalid config path: "+configPath, e);
1892 throw new IllegalArgumentException("Invalid config path: "+configPath);
1897 private String readConfigFile(String configPath){
1898 String configDataString = null;
1899 try(InputStream configContentStream = new FileInputStream(configPath);) {
1900 configDataString = IOUtils.toString(configContentStream);
1901 } catch (FileNotFoundException e) {
1902 logger.error("Caught FileNotFoundException on new FileInputStream("+configPath+")",e);
1903 throw new IllegalArgumentException("The config file path does not exist");
1904 } catch(IOException e2){
1905 logger.error("Caught IOException on newIOUtils.toString(configContentStream)",e2);
1906 throw new IllegalArgumentException("The config file path cannot be read");
1908 if(configDataString == null){
1909 throw new IllegalArgumentException("The config file path cannot be read");
1911 return configDataString;
1915 public void createPolicy(Policy policy, String username){
1918 logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy("+policy+","+username+") called");
1919 String policyScope = policy.policyAdapter.getDomainDir().replace(File.separator, ".");
1920 //Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
1921 //and this transaction is intercepted up stream.
1923 String policyDataString = getPolicyDataString((PolicyType)policy.getCorrectPolicyDataObject());
1925 //Using parentPath object to set policy data.
1926 policyDataString = policy.policyAdapter.getParentPath();
1928 String configPath = "";
1929 if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(config)) {
1930 configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString);
1931 } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(action)) {
1932 configPath = evaluateXPath("/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " +policy.policyAdapter.getActionAttribute()+ ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", policyDataString);
1935 String prefix = null;
1936 if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(config)) {
1938 prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.lastIndexOf(policy.policyAdapter.getPolicyName()));
1939 if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){
1940 policy.policyAdapter.setConfigBodyData(getConfigData(configPath));
1942 } else if (action.equalsIgnoreCase(policy.policyAdapter.getPolicyType())) {
1944 } else if ("Decision".equalsIgnoreCase(policy.policyAdapter.getPolicyType())) {
1945 prefix = "Decision_";
1948 if(!(policy.policyAdapter.getData() instanceof PolicyType)){
1949 PolicyLogger.error("The data field is not an instance of PolicyType");
1950 throw new IllegalArgumentException("The data field is not an instance of PolicyType");
1952 String finalName = policyScope + "." + prefix+policy.policyAdapter.getPolicyName()+"."+((PolicyType)policy.policyAdapter.getData()).getVersion()+".xml";
1953 if(policy.policyAdapter.getConfigType() == null || "".equals(policy.policyAdapter.getConfigType())){
1954 //get the config file extension
1956 if (configPath != null && !"".equalsIgnoreCase(configPath)) {
1957 ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());;
1960 if(ext.contains("txt")){
1961 policy.policyAdapter.setConfigType(OTHER_CONFIG);
1962 } else if(ext.contains("json")){
1963 policy.policyAdapter.setConfigType(JSON_CONFIG);
1964 } else if(ext.contains("xml")){
1965 policy.policyAdapter.setConfigType(XML_CONFIG);
1966 } else if(ext.contains("properties")){
1967 policy.policyAdapter.setConfigType(PROPERTIES_CONFIG);
1969 if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(action)){
1970 policy.policyAdapter.setConfigType(JSON_CONFIG);
1974 createPolicy(policy.policyAdapter, username, policyScope,finalName,policyDataString);
1975 } catch (Exception e) {
1976 logger.error("Could not create policy for "+policy,e);
1981 private String getConfigData(String configPath) {
1982 String configData = "";
1984 configData = getConfigPath(configPath);
1985 }catch(Exception e){
1986 logger.error("Could not read config body data for "+configPath,e);
1991 private String getConfigPath(String configPath) {
1993 String newConfigPath = processConfigPath(configPath);
1994 return readConfigFile(newConfigPath);
1995 } catch(IllegalArgumentException e2){
1996 logger.error("Could not process config path: "+configPath,e2);
2001 private String getPolicyDataString(PolicyType policyType) {
2002 try (InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream(policyType)) {
2003 return IOUtils.toString(policyXmlStream, StandardCharsets.UTF_8);
2004 } catch (IOException e) {
2005 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught IOException on IOUtils.toString(policyXmlStream)");
2006 throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter.", e);
2011 public void close(){
2012 synchronized(emLock){
2014 if(em.getTransaction().isActive()){
2015 em.getTransaction().rollback();
2019 if(transactionTimer != null){
2020 transactionTimer.interrupt();
2026 public void createGroup(String groupId, String groupName, String inputGroupDescription, String username) {
2027 String groupDescription = inputGroupDescription;
2028 logger.debug("deletePolicy(String policyToDeletes) as createGroup("+groupId+", "+groupName+", "+groupDescription+") called");
2029 if(isNullOrEmpty(groupId, groupName, username)){
2030 throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty");
2032 if(groupDescription == null){
2033 groupDescription = "";
2036 synchronized(emLock){
2037 checkBeforeOperationRun();
2038 Query checkGroupQuery = em.createQuery(groupEntitySelectQuery);
2039 checkGroupQuery.setParameter(groupIdVar, groupId);
2040 checkGroupQuery.setParameter(deletedVar, false);
2041 List<?> checkGroupQueryList;
2043 checkGroupQueryList = checkGroupQuery.getResultList();
2044 } catch(Exception e){
2045 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on checkGroupQuery.getResultList()");
2046 throw new PersistenceException(queryFailedToCheckExisting);
2048 if(!checkGroupQueryList.isEmpty()){
2049 PolicyLogger.error("The group being added already exists with id "+groupId);
2050 throw new PersistenceException("The group being added already exists with id "+groupId);
2052 GroupEntity newGroup = new GroupEntity();
2053 em.persist(newGroup);
2054 newGroup.setCreatedBy(username);
2055 newGroup.setModifiedBy(username);
2056 newGroup.setGroupName(groupName);
2057 newGroup.setGroupId(groupId);
2058 newGroup.setDescription(groupDescription);
2061 this.groupId = newGroup.getGroupKey();
2066 public void updateGroup(OnapPDPGroup group, String username){
2067 logger.info("PolicyDBDao: updateGroup(PDPGroup group) as updateGroup("+group+","+username+") called");
2069 throw new IllegalArgumentException("PDPGroup group must not be null");
2071 if(isNullOrEmpty(group.getId(), username)){
2072 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
2075 synchronized(emLock){
2076 checkBeforeOperationRun();
2077 Query getGroupQuery = em.createQuery(groupEntitySelectQuery);
2078 getGroupQuery.setParameter(groupIdVar, group.getId());
2079 getGroupQuery.setParameter(deletedVar, false);
2080 List<?> getGroupQueryList;
2082 getGroupQueryList = getGroupQuery.getResultList();
2083 } catch(Exception e){
2084 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on getGroupQuery.getResultList()");
2085 throw new PersistenceException(queryFailedToGetGroup+group.getId()+" for editing");
2087 if(getGroupQueryList.isEmpty()){
2088 PolicyLogger.error("The group cannot be found to update with id "+group.getId());
2089 throw new PersistenceException("The group cannot be found to update with id "+group.getId());
2090 } else if(getGroupQueryList.size() > 1){
2091 PolicyLogger.error(duplicateGroupId+group.getId()+deletedStatusFound);
2092 throw new PersistenceException(duplicateGroupId+group.getId()+deletedStatusFound);
2094 GroupEntity groupToUpdateInDB = (GroupEntity)getGroupQueryList.get(0);
2095 if(!stringEquals(groupToUpdateInDB.getModifiedBy(), username)){
2096 groupToUpdateInDB.setModifiedBy(username);
2098 if(group.getDescription() != null && !stringEquals(group.getDescription(),groupToUpdateInDB.getDescription())){
2099 groupToUpdateInDB.setDescription(group.getDescription());
2101 //let's find out what policies have been deleted
2102 StdPDPGroup oldGroup = null;
2104 oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId());
2105 } catch (PAPException e1) {
2106 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, "We cannot get the group from the papEngine to delete policies");
2108 if(oldGroup == null){
2109 PolicyLogger.error("We cannot get the group from the papEngine to delete policies");
2111 Set<String> newPolicySet = new HashSet<>(group.getPolicies().size());
2112 //a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison
2113 for(PDPPolicy pol: group.getPolicies()){
2114 newPolicySet.add(pol.getId());
2116 for(PDPPolicy pol : oldGroup.getPolicies()){
2117 //should be fast since getPolicies uses a HashSet in StdPDPGroup
2118 if(!newPolicySet.contains(pol.getId())){
2119 String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId());
2120 deletePolicyInScope(username, groupToUpdateInDB, pol, scopeAndName);
2125 if(group.getName() != null && !stringEquals(group.getName(),groupToUpdateInDB.getgroupName())){
2126 //we need to check if the new id exists in the database
2127 String newGroupId = createNewPDPGroupId(group.getName());
2128 Query checkGroupQuery = em.createQuery(groupEntitySelectQuery);
2129 checkGroupQuery.setParameter(groupIdVar, newGroupId);
2130 checkGroupQuery.setParameter(deletedVar, false);
2131 List<?> checkGroupQueryList;
2133 checkGroupQueryList = checkGroupQuery.getResultList();
2134 } catch(Exception e){
2135 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on checkGroupQuery.getResultList()");
2136 throw new PersistenceException(queryFailedToCheckExisting);
2138 if(!checkGroupQueryList.isEmpty()){
2139 PolicyLogger.error("The new group name already exists, group id "+newGroupId);
2140 throw new PersistenceException("The new group name already exists, group id "+newGroupId);
2142 groupToUpdateInDB.setGroupId(newGroupId);
2143 groupToUpdateInDB.setGroupName(group.getName());
2144 this.newGroupId = group.getId();
2147 this.groupId = groupToUpdateInDB.getGroupKey();
2151 private void deletePolicyInScope(String username, GroupEntity groupToUpdateInDB, PDPPolicy pol, String[] scopeAndName) {
2152 PolicyEntity policyToDelete;
2153 if (scopeAndName == null) {
2157 policyToDelete = getPolicy(scopeAndName[0],scopeAndName[1]);
2158 if ("XACMLPapServlet.doDelete".equals(username)) {
2159 Iterator<PolicyEntity> dbPolicyIt = groupToUpdateInDB.getPolicies().iterator();
2160 String policyName = getPolicyNameAndVersionFromPolicyFileName(policyToDelete.getPolicyName())[0];
2162 logger.info("PolicyDBDao: delete policy from GroupEntity");
2163 deletePolicyFromGroupEntity(groupToUpdateInDB, policyToDelete, dbPolicyIt, policyName);
2165 }catch(Exception e){
2166 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Could not get policy to remove: "+pol.getId());
2167 throw new PersistenceException("Could not get policy to remove: "+pol.getId());
2171 private void deletePolicyFromGroupEntity(GroupEntity groupToUpdateInDB, PolicyEntity policyToDelete, Iterator<PolicyEntity> dbPolicyIt, String policyName) {
2173 while(dbPolicyIt.hasNext()){
2174 PolicyEntity dbpolicy = dbPolicyIt.next();
2175 if(policyToDelete.getScope().equals(dbpolicy.getScope()) &&
2176 getPolicyNameAndVersionFromPolicyFileName(dbpolicy.getPolicyName())[0].equals(policyName)) {
2177 dbPolicyIt.remove();
2179 logger.info("PolicyDBDao: deleting policy from the existing group:\n "
2180 + "policyName is " + policyToDelete.getScope()+"."+policyToDelete.getPolicyName() + "\n"
2181 + "group is " + groupToUpdateInDB.getGroupId());
2184 }catch(Exception e){
2186 PolicyLogger.error("Could not delete policy with name: "+ policyToDelete.getScope()+"."+policyToDelete.getPolicyName()+"\n ID: "+ policyToDelete.getPolicyId());
2191 public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) {
2192 logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup("+pdpID+", "+groupID+", "+pdpName+", "+pdpDescription+", "+pdpJmxPort+", "+username+") called");
2193 if(isNullOrEmpty(pdpID, groupID,pdpName,username)){
2194 throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty");
2196 synchronized(emLock){
2197 checkBeforeOperationRun();
2198 Query checkGroupQuery = em.createQuery(groupEntitySelectQuery);
2199 checkGroupQuery.setParameter(groupIdVar, groupID);
2200 checkGroupQuery.setParameter(deletedVar, false);
2201 List<?> checkGroupQueryList;
2203 checkGroupQueryList = checkGroupQuery.getResultList();
2204 } catch(Exception e){
2205 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()");
2206 throw new PersistenceException(queryFailedToCheckExisting);
2208 if(checkGroupQueryList.size() != 1){
2209 PolicyLogger.error("The group does not exist");
2210 throw new PersistenceException("The group does not exist");
2212 Query checkDuplicateQuery = em.createQuery(pdpEntitySelectQuery);
2213 checkDuplicateQuery.setParameter(pdpIdVariable, pdpID);
2214 checkDuplicateQuery.setParameter(deletedVar, false);
2215 List<?> checkDuplicateList;
2217 checkDuplicateList = checkDuplicateQuery.getResultList();
2218 } catch(Exception e){
2219 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()");
2220 throw new PersistenceException("Query failed trying to check for duplicate PDP "+pdpID);
2223 if(!checkDuplicateList.isEmpty()){
2224 logger.warn("PDP already exists with id "+pdpID);
2225 newPdp = (PdpEntity)checkDuplicateList.get(0);
2227 newPdp = new PdpEntity();
2231 newPdp.setCreatedBy(username);
2232 newPdp.setDeleted(false);
2233 newPdp.setDescription(pdpDescription);
2234 newPdp.setGroup((GroupEntity)checkGroupQueryList.get(0));
2235 newPdp.setJmxPort(pdpJmxPort);
2236 newPdp.setModifiedBy(username);
2237 newPdp.setPdpId(pdpID);
2238 newPdp.setPdpName(pdpName);
2241 this.pdpId = newPdp.getPdpKey();
2247 public void updatePdp(OnapPDP pdp, String username){
2248 logger.debug("updatePdp(PDP pdp, String username) as updatePdp("+pdp+","+username+") called");
2250 throw new IllegalArgumentException("PDP pdp must not be null");
2252 if(isNullOrEmpty(pdp.getId(),username)){
2253 throw new IllegalArgumentException("pdp.getId() and username must not be null or empty");
2256 synchronized(emLock){
2257 checkBeforeOperationRun();
2258 Query getPdpQuery = em.createQuery(pdpEntitySelectQuery);
2259 getPdpQuery.setParameter(pdpIdVariable, pdp.getId());
2260 getPdpQuery.setParameter(deletedVar, false);
2261 List<?> getPdpQueryList;
2263 getPdpQueryList = getPdpQuery.getResultList();
2264 } catch(Exception e){
2265 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on getPdpQuery.getResultList()");
2266 throw new PersistenceException("Query failed trying to get PDP "+pdp.getId());
2268 if(getPdpQueryList.isEmpty()){
2269 PolicyLogger.error("The pdp cannot be found to update with id "+pdp.getId());
2270 throw new PersistenceException("The pdp cannot be found to update with id "+pdp.getId());
2271 } else if(getPdpQueryList.size() > 1){
2272 PolicyLogger.error(moreThanOnePDP+pdp.getId()+deletedStatusFound);
2273 throw new PersistenceException(moreThanOnePDP+pdp.getId()+deletedStatusFound);
2275 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
2276 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
2277 pdpToUpdate.setModifiedBy(username);
2279 if(pdp.getDescription() != null && !stringEquals(pdp.getDescription(),pdpToUpdate.getDescription())){
2280 pdpToUpdate.setDescription(pdp.getDescription());
2282 if(pdp.getName() != null && !stringEquals(pdp.getName(),pdpToUpdate.getPdpName())){
2283 pdpToUpdate.setPdpName(pdp.getName());
2285 if(pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())){
2286 pdpToUpdate.setJmxPort(pdp.getJmxPort());
2290 this.pdpId = pdpToUpdate.getPdpKey();
2295 public void movePdp(OnapPDP pdp, OnapPDPGroup group, String username){
2296 logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp("+pdp+","+group+","+username+") called");
2297 if(pdp == null || group == null){
2298 throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null");
2300 if(isNullOrEmpty(username,pdp.getId(),group.getId())){
2301 throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty");
2304 synchronized(emLock){
2305 checkBeforeOperationRun();
2306 //check if pdp exists
2307 Query getPdpQuery = em.createQuery(pdpEntitySelectQuery);
2308 getPdpQuery.setParameter(pdpIdVariable, pdp.getId());
2309 getPdpQuery.setParameter(deletedVar, false);
2310 List<?> getPdpQueryList;
2312 getPdpQueryList = getPdpQuery.getResultList();
2313 } catch(Exception e){
2314 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on getPdpQuery.getResultList()");
2315 throw new PersistenceException("Query failed trying to get pdp to move with id "+pdp.getId());
2317 if(getPdpQueryList.isEmpty()){
2318 PolicyLogger.error("The pdp cannot be found to move with id "+pdp.getId());
2319 throw new PersistenceException("The pdp cannot be found to move with id "+pdp.getId());
2320 } else if(getPdpQueryList.size() > 1){
2321 PolicyLogger.error(moreThanOnePDP+pdp.getId()+deletedStatusFound);
2322 throw new PersistenceException(moreThanOnePDP+pdp.getId()+deletedStatusFound);
2325 //check if new group exists
2326 Query checkGroupQuery = em.createQuery(groupEntitySelectQuery);
2327 checkGroupQuery.setParameter(groupIdVar, group.getId());
2328 checkGroupQuery.setParameter(deletedVar, false);
2329 List<?> checkGroupQueryList;
2331 checkGroupQueryList = checkGroupQuery.getResultList();
2332 } catch(Exception e){
2333 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get group on checkGroupQuery.getResultList()");
2334 throw new PersistenceException("Query failed trying to get new group "+group.getId());
2336 if(checkGroupQueryList.size() != 1){
2337 PolicyLogger.error("The group "+group.getId()+" does not exist");
2338 throw new PersistenceException("The group "+group.getId()+" does not exist");
2340 GroupEntity groupToMoveInto = (GroupEntity)checkGroupQueryList.get(0);
2341 PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0);
2342 pdpToUpdate.setGroup(groupToMoveInto);
2343 if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){
2344 pdpToUpdate.setModifiedBy(username);
2348 this.pdpId = pdpToUpdate.getPdpKey();
2353 public void changeDefaultGroup(OnapPDPGroup group, String username){
2354 logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup("+group+","+username+") called");
2356 throw new IllegalArgumentException("PDPGroup group must not be null");
2358 if(isNullOrEmpty(group.getId(),username)){
2359 throw new IllegalArgumentException("group.getId() and username must not be null or empty");
2362 synchronized(emLock){
2363 checkBeforeOperationRun();
2364 Query getGroupQuery = em.createQuery(groupEntitySelectQuery);
2365 getGroupQuery.setParameter(groupIdVar, group.getId());
2366 getGroupQuery.setParameter(deletedVar, false);
2367 List<?> getGroupQueryList;
2369 getGroupQueryList = getGroupQuery.getResultList();
2370 } catch(Exception e){
2371 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on getGroupQuery.getResultList()");
2372 throw new PersistenceException(queryFailedToGetGroup+group.getId());
2374 if(getGroupQueryList.isEmpty()){
2375 PolicyLogger.error("The group cannot be found to set default with id "+group.getId());
2376 throw new PersistenceException("The group cannot be found to set default with id "+group.getId());
2377 } else if(getGroupQueryList.size() > 1){
2378 PolicyLogger.error(duplicateGroupId+group.getId()+deletedStatusFound);
2379 throw new PersistenceException(duplicateGroupId+group.getId()+deletedStatusFound);
2381 GroupEntity newDefaultGroup = (GroupEntity)getGroupQueryList.get(0);
2382 newDefaultGroup.setDefaultGroup(true);
2383 if(!stringEquals(newDefaultGroup.getModifiedBy(), username)){
2384 newDefaultGroup.setModifiedBy(username);
2388 this.groupId = newDefaultGroup.getGroupKey();
2389 Query setAllGroupsNotDefault = em.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g.groupKey<>:groupKey");
2390 //not going to set modified by for all groups
2391 setAllGroupsNotDefault.setParameter("defaultGroup", false);
2392 setAllGroupsNotDefault.setParameter(deletedVar, false);
2393 setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey());
2395 logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default");
2396 } catch(Exception e){
2397 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception on setAllGroupsNotDefault.executeUpdate()");
2398 throw new PersistenceException("Could not set all other groups default to false");
2406 public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) throws PolicyDBException {
2407 logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called");
2409 throw new IllegalArgumentException("PDPGroup group cannot be null");
2411 if(isNullOrEmpty(username,group.getId())){
2412 throw new IllegalArgumentException("group.getId() and and username must not be null or empty");
2415 if(group.isDefaultGroup()){
2416 PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be.");
2417 throw new PolicyDBException("You cannot delete the default group.");
2419 synchronized(emLock){
2420 checkBeforeOperationRun();
2421 Query deleteGroupQuery = em.createQuery(groupEntitySelectQuery);
2422 deleteGroupQuery.setParameter(groupIdVar, group.getId());
2423 deleteGroupQuery.setParameter(deletedVar, false);
2424 List<?> deleteGroupQueryList;
2426 deleteGroupQueryList = deleteGroupQuery.getResultList();
2427 } catch(Exception e){
2428 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()");
2429 throw new PersistenceException("Query failed trying to check if group exists");
2431 if(deleteGroupQueryList.isEmpty()){
2432 logger.warn(groupCannotBeFound + group.getId());
2434 } else if(deleteGroupQueryList.size() > 1){
2435 PolicyLogger.error(duplicateGroupId+group.getId()+foundInDBNotDeleted);
2436 throw new PersistenceException(duplicateGroupId+group.getId()+foundInDBNotDeleted);
2439 Query pdpsInGroupQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted");
2440 pdpsInGroupQuery.setParameter("group", ((GroupEntity)deleteGroupQueryList.get(0)));
2441 pdpsInGroupQuery.setParameter(deletedVar, false);
2442 List<?> pdpsInGroupList;
2444 pdpsInGroupList = pdpsInGroupQuery.getResultList();
2445 } catch(Exception e){
2446 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()");
2447 throw new PersistenceException("Query failed trying to get PDPs in group");
2449 if(!pdpsInGroupList.isEmpty()){
2450 if(moveToGroup != null){
2451 Query checkMoveToGroupQuery = em.createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted");
2452 checkMoveToGroupQuery.setParameter(groupIdVar, moveToGroup.getId());
2453 checkMoveToGroupQuery.setParameter(deletedVar, false);
2454 List<?> checkMoveToGroupList;
2456 checkMoveToGroupList = checkMoveToGroupQuery.getResultList();
2457 } catch(Exception e){
2458 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()");
2459 throw new PersistenceException("Query failed trying to check if group exists");
2461 if(checkMoveToGroupList.isEmpty()){
2462 PolicyLogger.error(groupCannotBeFound + moveToGroup.getId());
2463 throw new PersistenceException(groupCannotBeFound + moveToGroup.getId());
2464 } else if(checkMoveToGroupList.size() > 1){
2465 PolicyLogger.error(duplicateGroupId+moveToGroup.getId()+foundInDBNotDeleted);
2466 throw new PersistenceException(duplicateGroupId+moveToGroup.getId()+foundInDBNotDeleted);
2468 GroupEntity newGroup = (GroupEntity)checkMoveToGroupList.get(0);
2469 for(Object pdpObject : pdpsInGroupList){
2470 PdpEntity pdp = (PdpEntity)pdpObject;
2471 pdp.setGroup(newGroup);
2472 if(!stringEquals(pdp.getModifiedBy(),username)){
2473 pdp.setModifiedBy(username);
2477 this.newGroupId = newGroup.getGroupId();
2478 } catch(PersistenceException e){
2479 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught PersistenceException trying to set pdp group to null on em.flush()");
2480 throw new PersistenceException("Query failed trying to set pdp group to ");
2485 PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to");
2486 throw new PolicyDBException("Group has PDPs. Must provide a group for them to move to");
2491 GroupEntity groupToDelete = (GroupEntity)deleteGroupQueryList.get(0);
2492 groupToDelete.setDeleted(true);
2493 if(!stringEquals(groupToDelete.getModifiedBy(), username)){
2494 groupToDelete.setModifiedBy(username);
2497 this.groupId = groupToDelete.getGroupKey();
2502 public StdPDPGroup addPolicyToGroup(String groupID, String policyID, String username) throws PolicyDBException {
2503 logger.info("PolicyDBDao: addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called");
2504 if(isNullOrEmpty(groupID, policyID, username)){
2505 throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty");
2507 synchronized(emLock){
2508 checkBeforeOperationRun();
2509 //check if group exists
2510 Query groupQuery = em.createQuery(groupEntitySelectQuery);
2511 groupQuery.setParameter(groupIdVar, groupID);
2512 groupQuery.setParameter(deletedVar, false);
2513 List<?> groupQueryList;
2515 groupQueryList = groupQuery.getResultList();
2516 }catch(Exception e){
2517 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if group exists groupQuery.getResultList()");
2518 throw new PersistenceException("Query failed trying to check if group "+groupID+" exists");
2520 if(groupQueryList.isEmpty()){
2521 PolicyLogger.error("Group policy is being added to does not exist with id "+groupID);
2522 throw new PersistenceException("Group policy is being added to does not exist with id "+groupID);
2523 } else if(groupQueryList.size() > 1){
2524 PolicyLogger.error(duplicateGroupId+groupID+foundInDBNotDeleted);
2525 throw new PersistenceException(duplicateGroupId+groupID+foundInDBNotDeleted);
2528 //we need to convert the form of the policy id that is used groups into the form that is used
2529 //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml)
2530 String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID);
2531 if(policyNameScopeAndVersion == null) {
2532 throw new IllegalArgumentException("Invalid input - policyID must contain name, scope and version");
2534 Query policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p.deleted=:deleted");
2535 policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]);
2536 policyQuery.setParameter(scope, policyNameScopeAndVersion[1]);
2537 policyQuery.setParameter(deletedVar, false);
2538 List<?> policyQueryList;
2540 policyQueryList = policyQuery.getResultList();
2541 } catch(Exception e){
2543 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if policy exists policyQuery.getResultList()");
2544 throw new PersistenceException("Query failed trying to check if policy "+policyNameScopeAndVersion[0]+" exists");
2546 if(policyQueryList.isEmpty()){
2547 PolicyLogger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
2548 throw new PersistenceException("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]);
2549 } else if(policyQueryList.size() > 1){
2550 PolicyLogger.error(duplicatePolicyId+policyNameScopeAndVersion[0]+foundInDBNotDeleted);
2551 throw new PersistenceException(duplicateGroupId+policyNameScopeAndVersion[0]+foundInDBNotDeleted);
2553 logger.info("PolicyDBDao: Getting group and policy from database");
2554 GroupEntity group = (GroupEntity)groupQueryList.get(0);
2555 PolicyEntity policy = (PolicyEntity)policyQueryList.get(0);
2556 Iterator<PolicyEntity> policyIt = group.getPolicies().iterator();
2557 String policyName = getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0];
2559 logger.info("PolicyDBDao: policyName retrieved is " + policyName);
2561 while(policyIt.hasNext()){
2562 PolicyEntity pol = policyIt.next();
2563 if(policy.getScope().equals(pol.getScope()) &&
2564 getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)) {
2568 }catch(Exception e){
2570 PolicyLogger.error("Could not delete old versions for policy "+policy.getPolicyName()+", ID: "+policy.getPolicyId());
2572 group.addPolicyToGroup(policy);
2575 // After adding policy to the db group we need to make sure the filesytem group is in sync with the db group
2577 StdPDPGroup pdpGroup = (StdPDPGroup) papEngine.getGroup(group.getGroupId());
2578 return synchronizeGroupPoliciesInFileSystem(pdpGroup, group);
2579 } catch (PAPException e) {
2581 PolicyLogger.error("PolicyDBDao: Could not synchronize the filesystem group with the database group. " + e.getMessage());
2587 //this means delete pdp not just remove from group
2589 public void removePdpFromGroup(String pdpID, String username) {
2590 logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup("+pdpID+","+username+") called");
2591 if(isNullOrEmpty(pdpID,username)){
2592 throw new IllegalArgumentException("pdpID and username must not be null or empty");
2594 synchronized(emLock){
2595 checkBeforeOperationRun();
2596 Query pdpQuery = em.createQuery(pdpEntitySelectQuery);
2597 pdpQuery.setParameter(pdpIdVariable, pdpID);
2598 pdpQuery.setParameter(deletedVar, false);
2601 pdpList = pdpQuery.getResultList();
2602 } catch(Exception e){
2603 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Caught Exception trying to check if pdp exists pdpQuery.getResultList()");
2604 throw new PersistenceException("Query failed trying to check if pdp "+pdpID+" exists");
2606 if(pdpList.size() > 1){
2607 PolicyLogger.error("Somehow, more than one pdp with the id "+pdpID+foundInDBNotDeleted);
2608 throw new PersistenceException("Somehow, more than one pdp with the id "+pdpID+foundInDBNotDeleted);
2609 } else if(pdpList.isEmpty()){
2610 PolicyLogger.error("Pdp being removed does not exist with id "+pdpID);
2613 PdpEntity pdp = (PdpEntity)pdpList.get(0);
2615 if(!stringEquals(pdp.getModifiedBy(),username)){
2616 pdp.setModifiedBy(username);
2618 pdp.setDeleted(true);
2621 this.pdpId = pdp.getPdpKey();
2625 private void notifyOthers(long entityId,String entityType){
2626 notifyOthers(entityId,entityType,null);
2629 private void notifyOthers(long entityId, String entityType, String newGroupId){
2630 logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers("+entityId+","+entityType+","+newGroupId+") called");
2631 LinkedList<Thread> notifyThreads = new LinkedList<>();
2633 //we're going to run notifications in parallel threads to speed things up
2634 for(Object obj : otherServers){
2635 Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId));
2636 newNotifyThread.start();
2637 notifyThreads.add(newNotifyThread);
2639 //we want to wait for all notifications to complete or timeout before we unlock the interface and allow more changes
2640 for(Thread t : notifyThreads){
2643 } catch (Exception e) {
2644 logger.warn("Could not join a notifcation thread" + e);
2650 private PolicyDBDao(){
2654 public static PolicyDBDaoTestClass getPolicyDBDaoTestClass(){
2655 return new PolicyDBDao().new PolicyDBDaoTestClass();
2658 final class PolicyDBDaoTestClass {
2659 String getConfigFile(String filename, String scope, PolicyRestAdapter policy){
2660 return scope + "." + PolicyDBDao.this.getConfigFile(filename, policy);
2662 String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException{
2663 return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName);