From 91d04c64771832a0b8815ffbe1f0f9920320d94d Mon Sep 17 00:00:00 2001 From: Pamela Dragosh Date: Tue, 14 Feb 2017 19:41:00 -0500 Subject: Initial OpenECOMP policy/engine commit Change-Id: I7dbff37733b661643dd4d1caefa3d7dccc361b6e Signed-off-by: Pamela Dragosh --- .../pap/xacml/rest/components/PolicyDBDao.java | 3936 ++++++++++++++++++++ 1 file changed, 3936 insertions(+) create mode 100644 ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java (limited to 'ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java') diff --git a/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java new file mode 100644 index 000000000..bdd7534d8 --- /dev/null +++ b/ECOMP-PAP-REST/src/main/java/org/openecomp/policy/pap/xacml/rest/components/PolicyDBDao.java @@ -0,0 +1,3936 @@ +/*- + * ============LICENSE_START======================================================= + * ECOMP-PAP-REST + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.policy.pap.xacml.rest.components; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.Key; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.LockModeType; +import javax.persistence.PersistenceException; +import javax.persistence.Query; +import javax.persistence.RollbackException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.policy.pap.xacml.rest.XACMLPapServlet; +import org.openecomp.policy.pap.xacml.rest.adapters.PolicyRestAdapter; +import org.openecomp.policy.rest.XACMLRestProperties; +import org.openecomp.policy.rest.jpa.ActionBodyEntity; +import org.openecomp.policy.rest.jpa.ConfigurationDataEntity; +import org.openecomp.policy.rest.jpa.DatabaseLockEntity; +import org.openecomp.policy.rest.jpa.GroupEntity; +import org.openecomp.policy.rest.jpa.PdpEntity; +import org.openecomp.policy.rest.jpa.PolicyDBDaoEntity; +import org.openecomp.policy.rest.jpa.PolicyEntity; +import org.openecomp.policy.rest.jpa.PolicyVersion; +import org.openecomp.policy.rest.util.Webapps; +import org.openecomp.policy.common.logging.eelf.MessageCodes; +import org.openecomp.policy.common.logging.eelf.PolicyLogger; + +import org.xml.sax.InputSource; + +import org.openecomp.policy.xacml.api.XACMLErrorConstants; +import org.openecomp.policy.xacml.api.pap.EcompPDP; +import org.openecomp.policy.xacml.api.pap.EcompPDPGroup; +import org.openecomp.policy.xacml.api.pap.PAPPolicyEngine; + +import com.att.research.xacml.api.pap.PAPEngine; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDP; +//import com.att.research.xacml.api.pap.PDPGroup; +import com.att.research.xacml.api.pap.PDPPolicy; +import org.openecomp.policy.xacml.std.pap.StdPDPGroup; +import org.openecomp.policy.xacml.std.pap.StdPDPPolicy; +import org.openecomp.policy.xacml.util.XACMLPolicyScanner; +import org.openecomp.policy.xacml.util.XACMLPolicyWriter; +import com.att.research.xacml.util.XACMLProperties; + +import org.w3c.dom.Document; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; +import org.openecomp.policy.common.logging.flexlogger.FlexLogger; +import org.openecomp.policy.common.logging.flexlogger.Logger; + +public class PolicyDBDao { + private static final Logger logger = FlexLogger.getLogger(PolicyDBDao.class); + private List otherServers; + private EntityManagerFactory emf; + private static PolicyDBDao currentInstance = null; + private PAPPolicyEngine papEngine; + + public static final String JSON_CONFIG = "JSON"; + public static final String XML_CONFIG = "XML"; + public static final String PROPERTIES_CONFIG = "PROPERTIES"; + public static final String OTHER_CONFIG = "OTHER"; + public static final String AUDIT_USER = "audit"; + + /** + * Get an instance of a PolicyDBDao. It creates one if it does not exist. + * Only one instance is allowed to be created per server. + * @param emf The EntityFactoryManager to be used for database connections + * @return The new instance of PolicyDBDao or throw exception if the given emf is null. + * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get this. + */ + public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) throws Exception{ + logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance("+emf+") called"); + if(currentInstance == null){ + if(emf != null){ + currentInstance = new PolicyDBDao(emf); + return currentInstance; + } + throw new IllegalStateException("The EntityManagerFactory is Null"); + } + return currentInstance; + } + + /** + * Gets the current instance of PolicyDBDao. + * @return The instance of PolicyDBDao or throws exception if the given instance is null. + * @throws IllegalStateException if a PolicyDBDao instance is null. Call createPolicyDBDaoInstance(EntityManagerFactory emf) to get this. + */ + public static PolicyDBDao getPolicyDBDaoInstance() throws Exception{ + logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called"); + if(currentInstance != null){ + return currentInstance; + } + throw new IllegalStateException("The PolicyDBDao.currentInstance is Null. Use getPolicyDBDao(EntityManagerFactory emf)"); + } + public void setPapEngine(PAPPolicyEngine papEngine2){ + this.papEngine = (PAPPolicyEngine) papEngine2; + } + private PolicyDBDao(EntityManagerFactory emf){ + logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao("+emf+") called"); + this.emf = emf; + + //not needed in this release + if(!register()){ + //TODO:EELF Cleanup - Remove logger + //logger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates"); + PolicyLogger.error("This server's PolicyDBDao instance could not be registered and may not reveive updates"); + } + + otherServers = getRemotePolicyDBDaoList(); + if(logger.isDebugEnabled()){ + logger.debug("Number of remote PolicyDBDao instances: "+otherServers.size()); + } + if(otherServers.size() < 1){ + logger.warn("List of PolicyDBDao servers is empty or could not be retrieved"); + } + //otherServers = new LinkedList(); + //otherServers.add((Object)"http://localhost:8071/pap/"); + } + + //not static because we are going to be using the instance's emf + //waitTime in ms to wait for lock, or -1 to wait forever (no) + private void startTransactionSynced(EntityManager entityMgr,int waitTime){ + logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as " + + "\n startTransactionSynced("+entityMgr+","+waitTime+") called\n\n"); + DatabaseLockEntity lock = null; + + entityMgr.setProperty("javax.persistence.query.timeout", waitTime); + entityMgr.getTransaction().begin(); + + if(logger.isDebugEnabled()){ + Map properties = entityMgr.getProperties(); + logger.debug("\n\nstartTransactionSynced():" + + "\n entityManager.getProperties() = " + properties + + "\n\n"); + } + try{ + if(logger.isDebugEnabled()){ + logger.debug("\n\nstartTransactionSynced():" + + "\n ATTEMPT to get the DB lock" + + "\n\n"); + } + lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE); + if(logger.isDebugEnabled()){ + logger.debug("\n\nstartTransactionSynced():" + + "\n GOT the DB lock" + + "\n\n"); + } + } catch(Exception e){ + System.out.println("Could not get lock entity"); + e.printStackTrace(); + } + if(lock == null){ + throw new IllegalStateException("The lock row does not exist in the table. Please create a primary key with value = 1."); + } + + } + /** + * Gets the list of other registered PolicyDBDaos from the database + * @return List (type PolicyDBDaoEntity) of other PolicyDBDaos + */ + private List getRemotePolicyDBDaoList(){ + logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called"); + List policyDBDaoEntityList = new LinkedList(); + EntityManager em = emf.createEntityManager(); + startTransactionSynced(em, 1000); + try{ + Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll"); + policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList(); + + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on: getPolicyDBDaoEntityQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception querying for other registered PolicyDBDaos"); + logger.warn("List of remote PolicyDBDaos will be empty"); + } + try{ + em.getTransaction().commit(); + } catch(Exception e){ + try{ + em.getTransaction().rollback(); + } catch(Exception e2){ + + } + } + em.close(); + return policyDBDaoEntityList; + } + + public PolicyDBDaoTransaction getNewTransaction(){ + logger.debug("getNewTransaction() as getNewTransaction() called"); + return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance()); + } + + /* + * Because the normal transactions are not used in audits, we can use the same transaction + * mechanism to get a transaction and obtain the emlock and the DB lock. We just need to + * provide different transaction timeout values in ms because the audit will run longer + * than normal transactions. + */ + public PolicyDBDaoTransaction getNewAuditTransaction(){ + logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called"); + //Use the standard transaction wait time in ms + int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)); + //Use the (extended) audit timeout time in ms + int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); + return (PolicyDBDaoTransaction)(new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs)); + } + + + /** + * Checks if two strings are equal. Null strings ARE allowed. + * @param one A String or null to compare + * @param two A String or null to compare + */ + private static boolean stringEquals(String one, String two){ + logger.debug("stringEquals(String one, String two) as stringEquals("+one+", "+two+") called"); + if(one == null && two == null){ + return true; + } + if(one == null || two == null){ + return false; + } + return one.equals(two); + } + + /** + * Computes the scope in dotted format based on an absolute path and a path that divides the scope. + * @param fullPath An absolute path including scope folders and other folders(does not have to be absolute, must just contain scope and other folders before) + * @param pathToExclude The path that acts as a division between the scope and the other folders + * @return The scope in dotted format (org.openecomp) + */ + private static String computeScope(String fullPath, String pathToExclude){ + logger.debug("computeScope(String fullPath, String pathToExclude) as computeScope("+fullPath+", "+pathToExclude+") called"); + int excludeIndex = fullPath.indexOf(pathToExclude); + String scopePath = fullPath.substring(excludeIndex+pathToExclude.length()); + String scope = scopePath.replace('\\', '.'); + scope = scope.replace('/', '.'); + if(scope.charAt(0) == '.'){ + scope = scope.substring(1); + } + if(scope.charAt(scope.length()-1) == '.'){ + scope = scope.substring(0, scope.length()-1); + } + return scope; + } + + /** + * Returns the url of this local pap server, removing the username and password, if they are present + * @return The url of this local pap server + */ + private String[] getPapUrlUserPass(){ + logger.debug("getPapUrl() as getPapUrl() called"); + String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL); + if(url == null){ + return null; + } + return splitPapUrlUserPass(url); + + + } + private String[] splitPapUrlUserPass(String url){ + String[] urlUserPass = new String[3]; + String[] commaSplit = url.split(","); + urlUserPass[0] = commaSplit[0]; + if(commaSplit.length > 2){ + urlUserPass[1] = commaSplit[1]; + urlUserPass[2] = commaSplit[2]; + } + if(urlUserPass[1] == null || urlUserPass[1].equals("")){ + String usernamePropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID); + if(usernamePropertyValue != null){ + urlUserPass[1] = usernamePropertyValue; + } + } + if(urlUserPass[2] == null || urlUserPass[2].equals("")){ + String passwordPropertyValue = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS); + if(passwordPropertyValue != null){ + urlUserPass[2] = passwordPropertyValue; + } + } + //if there is no comma, for some reason there is no username and password, so don't try to cut them off + return urlUserPass; + } + + private static String encryptPassword(String password) throws Exception{ + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, aesKey()); + byte[] encryption = cipher.doFinal(password.getBytes("UTF-8")); + System.out.println(encryption); + return new String(Base64.getMimeEncoder().encode(encryption),"UTF-8"); + } + + private static String decryptPassword(String encryptedPassword) throws Exception{ + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, aesKey()); + byte[] password = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword.getBytes("UTF-8"))); + return new String(password,"UTF-8"); + } + private static Key aesKey(){ + byte[] aesValue = (new String("njrmbklcxtoplawf")).getBytes(); + return new SecretKeySpec(aesValue,"AES"); + } + /** + * Register the PolicyDBDao instance in the PolicyDBDaoEntity table + * @return Boolean, were we able to register? + */ + private boolean register(){ + logger.debug("register() as register() called"); + String[] url = getPapUrlUserPass(); + EntityManager em = emf.createEntityManager(); + try{ + startTransactionSynced(em, 1000); + } catch(IllegalStateException e){ + logger.debug ("\nPolicyDBDao.register() caught an IllegalStateException: \n" +e + "\n"); + DatabaseLockEntity lock; + lock = em.find(DatabaseLockEntity.class, 1); + if(lock==null){ + lock = new DatabaseLockEntity(); + em.persist(lock); + lock.setKey(1); + try{ + em.flush(); + em.getTransaction().commit(); + em.close(); + } catch(Exception e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("COULD NOT CREATE DATABASELOCK ROW. WILL TRY ONE MORE TIME \n\n Exception: \n" + e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "COULD NOT CREATE DATABASELOCK ROW. WILL TRY ONE MORE TIME"); + e2.printStackTrace(); + } + em = null; + em = emf.createEntityManager(); + try{ + startTransactionSynced(em, 1000); + } catch(Exception e3){ + //still not working + String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING"; + //TODO:EELF Cleanup - Remove logger + //logger.error(msg); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, "PolicyDBDao", msg); + throw new IllegalStateException("msg" + "\n" + e3); + } + } + } + logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n"); + PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]); + Query getPolicyDBDaoEntityQuery = em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url"); + getPolicyDBDaoEntityQuery.setParameter("url", url[0]); + if(foundPolicyDBDaoEntity == null){ + //em.getTransaction().begin(); + PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity(); + em.persist(newPolicyDBDaoEntity); + newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]); + newPolicyDBDaoEntity.setDescription("PAP server at "+url[0]); + newPolicyDBDaoEntity.setUsername(url[1]); + try{ + newPolicyDBDaoEntity.setPassword(encryptPassword(url[2])); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not encrypt PAP password",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password"); + } + /* + try{ + em.getTransaction().commit(); + } catch(RollbackException e){ + logger.error("Caught RollbackException during PolicyDBDao Registration on: em.getTransaction().commit()",e); + em.close(); + return false; + } catch(Exception e2){ + logger.error("Caught Exception during PolicyDBDao Registration on: em.getTransaction().commit()",e2); + em.close(); + return false; + } + */ + try{ + em.getTransaction().commit(); + } catch(Exception e){ + try{ + em.getTransaction().rollback(); + } catch(Exception e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not add new PolicyDBDao to the database",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not add new PolicyDBDao to the database"); + } + } + } else { + //em.getTransaction().begin(); + //just want to update in order to change modified date + String encryptedPassword = null; + try{ + encryptedPassword = encryptPassword(url[2]); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not encrypt PAP password",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not encrypt PAP password"); + } + if(url[1] != null && !stringEquals(url[1], foundPolicyDBDaoEntity.getUsername())){ + foundPolicyDBDaoEntity.setUsername(url[1]); + } + if(encryptedPassword != null && !stringEquals(encryptedPassword, foundPolicyDBDaoEntity.getPassword())){ + foundPolicyDBDaoEntity.setPassword(encryptedPassword); + } + foundPolicyDBDaoEntity.preUpdate(); + try{ + em.getTransaction().commit(); + } catch(Exception e){ + try{ + em.getTransaction().rollback(); + } catch(Exception e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not update PolicyDBDao in the database",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Could not update PolicyDBDao in the database"); + } + } + /* + try{ + em.getTransaction().commit(); + } catch(RollbackException e){ + logger.error("Caught RollbackException during PolicyDBDao Registration on: em.getTransaction().commit()",e); + em.close(); + return false; + } catch(Exception e2){ + logger.error("Caught Exception during PolicyDBDao Registration on: em.getTransaction().commit()",e2); + em.getTransaction().rollback(); + return false; + } + */ + } + em.close(); + logger.debug("\nPolicyDBDao.register(). Success!!\n"); + return true; + } + public void notifyOthers(long entityId,String entityType){ + notifyOthers(entityId,entityType,null); + } + public void notifyOthers(long entityId, String entityType, String newGroupId){ + logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers("+entityId+","+entityType+","+newGroupId+") called"); + LinkedList notifyThreads = new LinkedList(); + + //we're going to run notiftions in parellel threads to speed things up + for(Object obj : otherServers){ + + Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId)); + + newNotifyThread.start(); + + notifyThreads.add(newNotifyThread); + + } + //we want to wait for all notifications to complete or timeout before we unlock the interface and allow more changes + for(Thread t : notifyThreads){ + try { + t.join(); + } catch (Exception e) { + logger.warn("Could not join a notifcation thread"); + } + } + + + } + + private class NotifyOtherThread implements Runnable { + public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId){ + this.obj = obj; + this.entityId = entityId; + this.entityType = entityType; + this.newGroupId = newGroupId; + } + private Object obj; + private long entityId; + private String entityType; + private String newGroupId; + @Override + public void run(){ + //naming of 'o' is for backwards compatibility with the rest of the function + PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity)obj; + String o = dbdEntity.getPolicyDBDaoUrl(); + String username = dbdEntity.getUsername(); + String password; + try{ + password = decryptPassword(dbdEntity.getPassword()); + } catch(Exception e){ + //if we can't decrypt, might as well try it anyway + password = dbdEntity.getPassword(); + } + Base64.Encoder encoder = Base64.getEncoder(); + String encoding = encoder.encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8)); + HttpURLConnection connection = null; + UUID requestID = UUID.randomUUID(); + //loggingContext.setRequestID(requestID.toString()); + //loggingContext.transactionStarted(); + URL url; + try { + String papUrl = getPapUrlUserPass()[0]; + if(papUrl == null){ + papUrl = "undefined"; + } + logger.debug("We are going to try to notify "+o); + //is this our own url? + String ourUrl = o; + try{ + ourUrl = splitPapUrlUserPass((String)o)[0]; + }catch(Exception e){ + ourUrl = o; + } + if(o == null){ + o = "undefined"; + } + if(papUrl.equals(ourUrl)){ + logger.debug(((String)o)+" is our url, skipping notify"); + return; + } + if(newGroupId == null){ + url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType); + } else { + url = new URL(((String)o)+"?policydbdaourl="+papUrl+"&entityid="+entityId+"&entitytype="+entityType+"&extradata="+newGroupId); + } + } catch (MalformedURLException e) { + logger.warn("Caught MalformedURLException on: new URL()", e); + return; + } + // + // Open up the connection + // + logger.debug("Connecting with url: "+url); + try { + connection = (HttpURLConnection)url.openConnection(); + } catch (Exception e) { + logger.warn("Caught exception on: url.openConnection()",e); + return; + } + // + // Setup our method and headers + // + try { + connection.setRequestMethod("PUT"); + } catch (ProtocolException e) { + //why would this error ever occur? + logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");",e); + return; + } + connection.setRequestProperty("Authorization", "Basic " + encoding); + connection.setRequestProperty("Accept", "text/x-java-properties"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + connection.setRequestProperty("requestID", requestID.toString()); + int readTimeout; + try{ + readTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT)); + + } catch(Exception e){ + logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default."); + readTimeout = 10000; + } + connection.setReadTimeout(readTimeout); + connection.setConnectTimeout(readTimeout); + connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + try { + connection.connect(); + } catch (Exception e) { + logger.warn("Caught exception on: connection.connect()",e); + return; + } + try { + if (connection.getResponseCode() == 200) { + logger.info("Received response 200 from pap server on notify"); + //notified = true; + } else { + logger.warn("connection response code not 200, received: "+connection.getResponseCode()); + } + } catch (Exception e) { + logger.warn("Caught Exception on: connection.getResponseCode() ", e); + } + + + connection.disconnect(); + } + } + + private static String getElementFromXMLString(String element, String xml) { + InputSource source = new InputSource(new StringReader(xml)); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + String description = ""; + try{ + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(source); + + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + + if (element.endsWith("/")){ + element = element.substring(0, element.length() -1); + } + + description = xpath.evaluate("/Policy" + element + "/text()", document); + }catch(Exception e){ + + } + + + System.out.println("description_" + description); + return description; + } + private static String evaluateXPath(String expression, String xml) { + InputSource source = new InputSource(new StringReader(xml)); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + String description = ""; + try{ + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(source); + + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + + + description = xpath.evaluate(expression, document); + }catch(Exception e){ + + } + + + System.out.println("description_" + description); + return description; + } + + private static String getDescriptionFromXacml(String xacmlData){ + //FIXME completely untested. Probably not a good idea to use. UPDATE: kind of tested + String openTag = ""; + String closeTag = ""; + int descIndex = xacmlData.indexOf(openTag); + int endDescIndex = xacmlData.indexOf(closeTag); + String desc = xacmlData.substring(descIndex+openTag.length(),endDescIndex); + return desc; + } + private final String POLICY_NOTIFICATION = "policy"; + private final String PDP_NOTIFICATION = "pdp"; + private final String GROUP_NOTIFICATION = "group"; + public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, XACMLPapServlet xacmlPapServlet){ + logger.info("DBDao url: " + url + " has reported an update on "+entityType+" entity "+entityId); + PolicyDBDaoTransaction transaction = this.getNewTransaction(); + switch(entityType){ + + case POLICY_NOTIFICATION: + try{ + handleIncomingPolicyChange(url, entityId,extraData); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPolicyChange("+url+", "+entityId+", "+extraData+")"); + } + break; + case PDP_NOTIFICATION: + try{ + handleIncomingPdpChange(url, entityId, transaction); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingPdpChange("+url+", "+entityId+", "+transaction+")"); + } + break; + case GROUP_NOTIFICATION: + try{ + handleIncomingGroupChange(url, entityId, extraData, transaction, xacmlPapServlet); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught exception on handleIncomingGroupChange("+url+", "+entityId+", "+extraData+", "+transaction+", "+xacmlPapServlet+")"); + } + break; + } + //no changes should be being made in this function, we still need to close + transaction.rollbackTransaction(); + } + private void handleIncomingGroupChange(String url, String groupId, String extraData,PolicyDBDaoTransaction transaction,XACMLPapServlet xacmlPapServlet) throws PAPException{ + + GroupEntity groupRecord = null; + long groupIdLong = -1; + try{ + groupIdLong = Long.parseLong(groupId); + } catch(NumberFormatException e){ + throw new IllegalArgumentException("groupId "+groupId+" cannot be parsed into a long"); + } + try{ + groupRecord = transaction.getGroup(groupIdLong); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp group record with transaction.getGroup("+groupIdLong+");"); + throw new PAPException("Could not get local group "+groupIdLong); + } + if(groupRecord == null){ + throw new PersistenceException("The group record returned is null"); + } + //compare to local fs + //does group folder exist + EcompPDPGroup localGroup = null; + try { + localGroup = papEngine.getGroup(groupRecord.getGroupId()); + } catch (Exception e) { + logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+groupId+");",e); + //throw new PAPException("Could not get local group "+groupId); + } + if(localGroup == null && extraData != null){ + //here we can try to load an old group id from the extraData + try{ + localGroup = papEngine.getGroup(extraData); + }catch(Exception e){ + logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup("+extraData+");",e); + } + } + if(localGroup != null && groupRecord.isDeleted()){ + EcompPDPGroup newLocalGroup = null; + if(extraData != null){ + try { + newLocalGroup = papEngine.getGroup(extraData); + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get new pdp group with papEngine.getGroup("+extraData+");"); + //throw new PAPException("Could not get new local group "+newGroupId); + + } + } + try { + papEngine.removeGroup(localGroup, newLocalGroup); + } catch (NullPointerException | PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp group with papEngine.removeGroup("+localGroup+", "+newLocalGroup+");"); + throw new PAPException("Could not remove group "+groupId); + } + } + else if(localGroup == null){ + //creating a new group + try { + papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription()); + } catch (NullPointerException | PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());"); + throw new PAPException("Could not create group "+groupRecord); + } + try { + localGroup = papEngine.getGroup(groupRecord.getGroupId()); + } catch (PAPException e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("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",e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get pdp group we just created with papEngine.getGroup(groupRecord.getGroupId());\nAny PDPs or policies in the new group may not have been added"); + return; + //throw new PAPException("Could not get group "+groupRecord); + } + //add possible pdps to group + List pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId())); + for(Object pdpO : pdpsInGroup){ + PdpEntity pdp = (PdpEntity)pdpO; + try { + papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort()); + } catch (NullPointerException | PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());"); + throw new PAPException("Could not create pdp "+pdp); + } + } + //add possible policies to group (filesystem only, apparently) + } else { + if(!(localGroup instanceof StdPDPGroup)){ + throw new PAPException("group is not a StdPDPGroup"); + } + //clone the object + //because it will be comparing the new group to its own version + StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(),localGroup.isDefaultGroup(),localGroup.getName(),localGroup.getDescription(),((StdPDPGroup)localGroup).getDirectory()); + localGroupClone.setEcompPdps(localGroup.getEcompPdps()); + localGroupClone.setPipConfigs(localGroup.getPipConfigs()); + localGroupClone.setStatus(localGroup.getStatus()); + //we are updating a group or adding a policy or changing default + //set default if it should be + if(!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()){ + try { + papEngine.SetDefaultGroup(localGroup); + return; + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to set default group with papEngine.SetDefaultGroup("+localGroupClone+");"); + throw new PAPException("Could not set default group to "+localGroupClone); + } + } + boolean needToUpdate = false; + if(updateGroupPoliciesInFileSystem(localGroupClone,localGroup, groupRecord, transaction)){ + needToUpdate = true; + } + if(!stringEquals(localGroupClone.getId(),groupRecord.getGroupId()) || !stringEquals(localGroupClone.getName(),groupRecord.getgroupName())){ + //changing ids + //we do not want to change the id, the papEngine will do this for us, it needs to know the old id + localGroupClone.setName(groupRecord.getgroupName()); + needToUpdate = true; + } + if(!stringEquals(localGroupClone.getDescription(),groupRecord.getDescription())){ + localGroupClone.setDescription(groupRecord.getDescription()); + needToUpdate = true; + } + if(needToUpdate){ + try { + + papEngine.updateGroup(localGroupClone); + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update group with papEngine.updateGroup("+localGroupClone+");"); + throw new PAPException("Could not update group "+localGroupClone); + } + } + + } + //call command that corresponds to the change that was made + } + //this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add them all in from the db + private boolean updateGroupPoliciesInFileSystem(EcompPDPGroup pdpGroup,EcompPDPGroup oldPdpGroup, GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException{ + if(!(pdpGroup instanceof StdPDPGroup)){ + throw new PAPException("group is not a StdPDPGroup"); + } + StdPDPGroup group = (StdPDPGroup)pdpGroup; + //this must always be true since we don't explicitly know when a delete is occuring + boolean didUpdate = true; + HashMap currentPolicySet = new HashMap(oldPdpGroup.getPolicies().size()); + HashSet newPolicySet = new HashSet(); + for(PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()){ + currentPolicySet.put(pdpPolicy.getId(), pdpPolicy); + } + for(PolicyEntity policy : groupRecord.getPolicies()){ + String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope()); + if(group.getPolicy(pdpPolicyName) == null){ + didUpdate = true; + if(currentPolicySet.containsKey(pdpPolicyName)){ + newPolicySet.add(currentPolicySet.get(pdpPolicyName)); + } else{ + InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); + group.copyPolicyToFile(pdpPolicyName,policyStream); + ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(policy.getPolicyName())); + try { + policyStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + if(didUpdate){ + newPolicySet.addAll(group.getPolicies()); + group.setPolicies(newPolicySet); + } + return didUpdate; + + } + private String removeExtensionAndVersionFromPolicyName(String originalPolicyName){ + String policyName = originalPolicyName; + try{ + policyName = removeFileExtension(policyName); + policyName = policyName.substring(0,policyName.lastIndexOf('.')); + if(isNullOrEmpty(policyName)){ + throw new Exception(); + } + } catch(Exception e){ + policyName = originalPolicyName; + } + return policyName; + } + + private void handleIncomingPdpChange(String url, String pdpId, PolicyDBDaoTransaction transaction) throws PAPException{ + //get pdp + long pdpIdLong = -1; + try{ + pdpIdLong = Long.parseLong(pdpId); + }catch(NumberFormatException e){ + throw new IllegalArgumentException("pdpId "+pdpId+" cannot be parsed into a long"); + } + PdpEntity pdpRecord = null; + try{ + pdpRecord = transaction.getPdp(pdpIdLong); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp record with transaction.getPdp("+pdpIdLong+");"); + throw new PAPException("Could not get local pdp "+pdpIdLong); + } + if(pdpRecord == null){ + throw new PersistenceException("The pdpRecord returned is null"); + } + PDP localPdp = null; + try { + localPdp = papEngine.getPDP(pdpRecord.getPdpId()); + } catch (PAPException e) { + logger.warn("Caught PAPException trying to get local pdp with papEngine.getPDP("+pdpId+");",e); + } + if(localPdp != null && pdpRecord.isDeleted()){ + try { + papEngine.removePDP((EcompPDP) localPdp); + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get remove pdp with papEngine.removePDP("+localPdp+");"); + throw new PAPException("Could not remove pdp "+pdpId); + } + } + else if(localPdp == null){ + //add new pdp + //get group + + EcompPDPGroup localGroup = null; + try { + localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId()); + } catch (PAPException e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());",e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());"); + throw new PAPException("Could not get local group"); + } + try { + papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort()); + } catch (NullPointerException | PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to create pdp with papEngine.newPDP("+pdpRecord.getPdpId()+", "+localGroup+", "+pdpRecord.getPdpName()+", "+pdpRecord.getDescription()+", "+pdpRecord.getJmxPort()+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to create pdp with papEngine.newPDP("+pdpRecord.getPdpId()+", "+localGroup+", "+pdpRecord.getPdpName()+", "+pdpRecord.getDescription()+", "+pdpRecord.getJmxPort()+");"); + throw new PAPException("Could not create pdp "+pdpRecord); + } + } else { + boolean needToUpdate = false; + if(!stringEquals(localPdp.getId(),pdpRecord.getPdpId()) || !stringEquals(localPdp.getName(),pdpRecord.getPdpName())){ + //again, we don't want to change the id, the papEngine will do this + localPdp.setName(pdpRecord.getPdpName()); + needToUpdate = true; + } + if(!stringEquals(localPdp.getDescription(),pdpRecord.getDescription())){ + localPdp.setDescription(pdpRecord.getDescription()); + needToUpdate = true; + } + String localPdpGroupId = null; + try{ + localPdpGroupId = papEngine.getPDPGroup((EcompPDP) localPdp).getId(); + } catch(PAPException e){ + //could be null or something, just warn at this point + logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();",e); + //throw new PAPException("Could not get local group"); + } + if(!stringEquals(localPdpGroupId,pdpRecord.getGroup().getGroupId())){ + EcompPDPGroup newPdpGroup = null; + try{ + newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId()); + }catch(PAPException e){ + //ok, now we have an issue. Time to stop things + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());"); + throw new PAPException("Could not get local group"); + } + try{ + papEngine.movePDP((EcompPDP) localPdp, newPdpGroup); + }catch(PAPException e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);"); + throw new PAPException("Could not move pdp "+localPdp); + } + } + if(((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()){ + ((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort()); + needToUpdate = true; + } + if(needToUpdate){ + try { + papEngine.updatePDP((EcompPDP) localPdp); + } catch (PAPException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PAPException trying to update pdp with papEngine.updatePdp("+localPdp+");"); + throw new PAPException("Could not update pdp "+localPdp); + } + } + } + //compare to local situation + //call command to update + } + private void handleIncomingPolicyChange(String url, String policyId,String oldPathString){ + EntityManager em = emf.createEntityManager(); + Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById"); + getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId)); + + @SuppressWarnings("unchecked") + List policies = getPolicyEntityQuery.getResultList(); + PolicyEntity policy = null; + if (policies.size() > 0){ + policy = policies.get(0); + } + + String policyRepo = buildPolicyScopeDirectory(policy); + + Path policyPath = Paths.get(policyRepo); + String action = "unknown action"; + try { + + if(policy.isDeleted()){ + logger.debug("Deleting Policy: " + policy.getPolicyName()); + action = "delete"; + Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName()); + Files.deleteIfExists(newPath); + + Path subFile = null; + + if (policy.getConfigurationData()!= null){ + subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), "Config"); + }else if(policy.getActionBodyEntity()!= null){ + subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), "Action"); + } + + if(subFile != null){ + Files.deleteIfExists(subFile); + } + + }else{ + logger.debug("Updating/Creating Policy: " + policy.getPolicyName()); + action = "update"; + Files.createDirectories(policyPath); + Path newPath = Paths.get(policyPath.toString(), policy.getPolicyName()); + Files.deleteIfExists(newPath); + if(!isNullOrEmpty(oldPathString)){ + try{ + String[] scopeName = getScopeAndNameAndType(oldPathString); + Path oldPath = Paths.get(buildPolicyScopeDirectory(scopeName[0]),scopeName[1]); + Files.delete(oldPath.toAbsolutePath()); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not delete the old policy before rename: "+oldPathString,e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy before rename: "+oldPathString); + } + } + Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData())); + XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData); + + if (policy.getConfigurationData()!= null){ + if(!isNullOrEmpty(oldPathString)){ + try{ + String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString); + String oldConfigFileName = getConfigFile(oldPolicyScopeName[1],oldPolicyScopeName[0],policy.getConfigurationData().getConfigType()); + Path oldConfigFilePath = getPolicySubFile(oldConfigFileName, "Config"); + logger.debug("Trying to delete: "+oldConfigFilePath.toString()); + Files.delete(oldConfigFilePath); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not delete the old policy config before rename for policy: "+oldPathString,e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy config before rename for policy: "+oldPathString); + } + } + writePolicySubFile(policy, "Config"); + + }else if(policy.getActionBodyEntity()!= null){ + if(!isNullOrEmpty(oldPathString)){ + try{ + String[] oldPolicyScopeName = getScopeAndNameAndType(oldPathString); + String oldActionFileName = getConfigFile(oldPolicyScopeName[1],oldPolicyScopeName[0],ConfigPolicy.JSON_CONFIG); + Path oldActionFilePath = getPolicySubFile(oldActionFileName, "Action"); + logger.debug("Trying to delete: "+oldActionFilePath.toString()); + Files.delete(oldActionFilePath); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not delete the old policy action body before rename for policy: "+oldPathString,e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not delete the old policy action body before rename for policy: "+oldPathString); + } + } + writePolicySubFile(policy, "Action"); + } + + } + } catch (IOException e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Error occurred while performing [" + action + "] of Policy File: " + policy.getPolicyName(), e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while performing [" + action + "] of Policy File: " + policy.getPolicyName()); + } + } + + //FIXME error correcting and logs + private void createGroupsFromDatabase(){ + //get list of groups + boolean foundDefault = false; + //need to avoid infinite loop, just in case + boolean alreadyRunAdd = false; + while(!foundDefault){ + + EntityManager em = emf.createEntityManager(); + Query getGroups = em.createQuery("SELECT g FROM GroupEntity g WHERE g.deleted=:deleted"); + getGroups.setParameter("deleted", false); + List groups = getGroups.getResultList(); + em.close(); + //make a folder for each group in pdps folders + Path pdpsPath = Paths.get("pdps"); + try { + FileUtils.forceDelete(pdpsPath.toFile()); + } catch (Exception e) { + e.printStackTrace(); + } + try { + FileUtils.forceMkdir(pdpsPath.toFile()); + } catch (Exception e) { + e.printStackTrace(); + } + Properties propertyFileProperties = new Properties(); + String groupList = ""; + String defaultGroup = ""; + for(Object o : groups){ + GroupEntity group = (GroupEntity)o; + Path groupPath = Paths.get(pdpsPath.toString(), group.getGroupId()); + try { + FileUtils.forceMkdir(groupPath.toFile()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Properties policyProperties = new Properties(); + String rootPolicies = ""; + for(PolicyEntity policy : group.getPolicies()){ + Path newPolicyPath = Paths.get(groupPath.toString(),getPdpPolicyName(policy.getPolicyName(),policy.getScope())); + File newPolicyFile = newPolicyPath.toFile(); + try { + newPolicyFile.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + FileOutputStream policyFileStream = new FileOutputStream(newPolicyFile); + policyFileStream.write(policy.getPolicyData().getBytes("UTF-8")); + policyFileStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + policyProperties.setProperty(getPdpPolicyName(policy.getPolicyName(),policy.getScope())+".name",removeExtensionAndVersionFromPolicyName(policy.getPolicyName())); + rootPolicies += ",".concat(getPdpPolicyName(policy.getPolicyName(),policy.getScope())); + } + Path xacmlPolicyPropertiesPath = Paths.get(groupPath.toString(),"xacml.policy.properties"); + File xacmlPolicyPropertiesFile = xacmlPolicyPropertiesPath.toFile(); + if(rootPolicies.length() > 0){ + rootPolicies = rootPolicies.substring(1); + } + policyProperties.setProperty("xacml.referencedPolicies", ""); + policyProperties.setProperty("xacml.rootPolicies", rootPolicies); + + try { + xacmlPolicyPropertiesFile.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + FileOutputStream xacmlPolicyPropertiesFileStream = new FileOutputStream(xacmlPolicyPropertiesFile); + //xacmlPolicyPropertiesFileStream.write(xacmlPolicyProperties.getBytes("UTF-8")); + policyProperties.store(xacmlPolicyPropertiesFileStream, ""); + xacmlPolicyPropertiesFileStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + em = emf.createEntityManager(); + Query getPdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group AND p.deleted=:deleted"); + getPdpsQuery.setParameter("group", group); + getPdpsQuery.setParameter("deleted", false); + List pdps = getPdpsQuery.getResultList(); + em.close(); + String pdpLine = ""; + for(Object o2 : pdps){ + PdpEntity pdp = (PdpEntity)o2; + pdpLine += ",".concat(pdp.getPdpId()); + propertyFileProperties.setProperty(pdp.getPdpId()+".description",pdp.getDescription()); + propertyFileProperties.setProperty(pdp.getPdpId()+".jmxport",String.valueOf(pdp.getJmxPort())); + propertyFileProperties.setProperty(pdp.getPdpId()+".name",pdp.getPdpName()); + } + if(pdpLine.length() > 0){ + pdpLine = pdpLine.substring(1); + } + propertyFileProperties.setProperty(group.getGroupId()+".description", group.getDescription()); + propertyFileProperties.setProperty(group.getGroupId()+".name", group.getgroupName()); + propertyFileProperties.setProperty(group.getGroupId()+".pdps",pdpLine); + groupList += ",".concat(group.getGroupId()); + if(group.isDefaultGroup()){ + defaultGroup = group.getGroupId(); + foundDefault = true; + } + } + if(!foundDefault && !alreadyRunAdd){ + alreadyRunAdd = true; + //add default group to db + try{ + em = emf.createEntityManager(); + em.getTransaction().begin(); + GroupEntity newDefaultGroup = new GroupEntity(); + em.persist(newDefaultGroup); + newDefaultGroup.setDescription("The default group where new PDP's are put."); + newDefaultGroup.setGroupId("default"); + newDefaultGroup.setGroupName("default"); + newDefaultGroup.setDefaultGroup(true); + newDefaultGroup.setCreatedBy("automaticallyAdded"); + newDefaultGroup.setModifiedBy("automaticallyAdded"); + em.flush(); + em.getTransaction().commit(); + continue; + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not add a new default group to the database",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not add a new default group to the database"); + } + } + + Path xacmlPropertiesPath = Paths.get(pdpsPath.toString(),"xacml.properties"); + File xacmlPropertiesFile = xacmlPropertiesPath.toFile(); + if(groupList.length()>0){ + groupList = groupList.substring(1); + } + propertyFileProperties.setProperty("xacml.pap.groups",groupList); + propertyFileProperties.setProperty("xacml.pap.groups.default",defaultGroup); + try { + xacmlPropertiesFile.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + FileOutputStream xacmlPropertiesFileStream = new FileOutputStream(xacmlPropertiesFile); + //xacmlPropertiesFileStream.write(fileContents.getBytes("UTF-8")); + propertyFileProperties.store(xacmlPropertiesFileStream, ""); + xacmlPropertiesFileStream.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //if we get this far down, something went wrong and we don't want to get stuck in the loop + foundDefault = true; + } + //put policies in group folder + //create xacml.policy.properties in each folder with list of policies in that folder + //get list of pdps + //create xacml.properties with list of groups and pdps and other info + } + + + //FIXME error checking and logging + private String getPdpPolicyName(String name, String scope){ + String finalName = ""; + finalName += scope; + finalName += "."; + finalName += removeFileExtension(name); + finalName += ".xml"; + return finalName; + } + private String removeFileExtension(String fileName){ + return fileName.substring(0, fileName.lastIndexOf('.')); + } + + private String buildPolicyScopeDirectory(PolicyEntity policy){ + String repo = buildPolicyDirectory(); + + String policyScope = policy.getScope(); + if(policyScope == null){ + policyScope = ""; + //TODO:EELF Cleanup - Remove logger + //logger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank."); + PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank."); + } else { + policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator()); + } + if(policyScope == null){ + policyScope = ""; + //TODO:EELF Cleanup - Remove logger + //logger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank."); + PolicyLogger.error("buildPolicyScopeDirectory("+policy+") computed null policyScope. Using blank."); + } + if(repo == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank."); + PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank."); + repo = ""; + } + Path returnPath = Paths.get(repo + FileSystems.getDefault().getSeparator() + policyScope); + if(returnPath != null){ + return returnPath.toString(); + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error("buildPolicyScopeDirectory("+policy+") computed null path"); + PolicyLogger.error("buildPolicyScopeDirectory("+policy+") received null repo. Using blank."); + return ""; + } + + + } + private String buildPolicyScopeDirectory(String policyScope){ + String repo = buildPolicyDirectory(); + policyScope = policyScope.replace(".", FileSystems.getDefault().getSeparator()); + return repo + FileSystems.getDefault().getSeparator() + policyScope; + + } + + private static String buildPolicyDirectory(){ + Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), getDefaultWorkspace()); + Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY)); + Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString()); + + /* + * Getting and Setting the parent path for Admin Console use when reading the policy files + */ + //domain chosen by the client to store the policy action files + //String domain = policy.getDomainDir(); + + + + //getting the fullpath of the gitPath and convert to string + String policyDir = gitPath.toAbsolutePath().toString(); + + + if(policyDir.contains("\\")){ + policyDir = policyDir.replace("XACML-PAP-REST", "XACML-PAP-ADMIN"); + }else{ + if (policyDir.contains("pap")){ + policyDir = policyDir.replace("pap", "console"); + } + } + logger.debug("policyDir: " + policyDir); + return policyDir; + } + + private Path getPolicySubFile(String filename, String subFileType){ + logger.debug("getPolicySubFile(" + filename + ", " + subFileType + ")"); + Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), subFileType); + File file = null; + + filename = FilenameUtils.removeExtension(filename); + + for(File tmpFile : filePath.toFile().listFiles()){ + if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)){ + file = tmpFile; + } + } + + Path finalPath = null; + if (file!= null){ + finalPath = Paths.get(file.getAbsolutePath()); + } + + logger.debug("end of getPolicySubFile: " + finalPath); + return finalPath; + } + + private boolean writePolicySubFile(PolicyEntity policy, String policyType){ + logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + "]"); + String type = null; + String subTypeName = null; + String subTypeBody = null; + if (policyType.equalsIgnoreCase("config")){ + type = "Config"; + subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName()); + subTypeBody = policy.getConfigurationData().getConfigBody(); + + String configType = policy.getConfigurationData().getConfigType(); + + + if (configType != null) { + if (configType.equals(JSON_CONFIG)) { + subTypeName = subTypeName + ".json"; + } + if (configType.equals(XML_CONFIG)) { + subTypeName = subTypeName + ".xml"; + } + if (configType.equals(PROPERTIES_CONFIG)) { + subTypeName = subTypeName + ".properties"; + } + if (configType.equals(OTHER_CONFIG)) { + subTypeName = subTypeName + ".txt"; + } + } + + }else if (policyType.equalsIgnoreCase("action")){ + type = "Action"; + subTypeName = policy.getActionBodyEntity().getActionBodyName(); + subTypeBody = policy.getActionBodyEntity().getActionBody(); + + + } + Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type); + + if(subTypeBody == null){ + subTypeBody = ""; + } + boolean success = false; + try { + Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName)); + File file = Paths.get(filePath.toString(),subTypeName).toFile(); + file.createNewFile(); + FileWriter fileWriter = new FileWriter(file, false); // false to overwrite + fileWriter.write(subTypeBody); + fileWriter.close(); + success = true; + + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Exception occured while creating Configuration File for Policy : " + policy.getPolicyName(), e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName()); + } + + return success; + + } + + private String getPolicySubType(String filename){ + String type = null; + + if (filename != null) { + if (FilenameUtils.getExtension(filename).equalsIgnoreCase("json")) { + type = ConfigPolicy.JSON_CONFIG; + } + if (FilenameUtils.getExtension(filename).equalsIgnoreCase("xml")) { + type = ConfigPolicy.XML_CONFIG; + } + if (FilenameUtils.getExtension(filename).equalsIgnoreCase("properties")) { + type = ConfigPolicy.PROPERTIES_CONFIG; + } + if (FilenameUtils.getExtension(filename).equalsIgnoreCase("txt")) { + type = ConfigPolicy.OTHER_CONFIG; + } + } + + return type; + + } + + + private void convertFileToDBEntry(Path path){ + logger.info("convertFileToDBEntry"); + + if(path.toString().contains(".git")){ + return; + } + + String filename = path.getFileName().toString(); + if (filename.contains(".svnignore")){ + return; + } + + String[] scopeAndName = getScopeAndNameAndType(path.toString()); + + if(scopeAndName == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + path.toString() + " is null!"); + PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + path.toString() + " is null!"); + return; + } + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + PolicyEntity policy = new PolicyEntity(); + em.persist(policy); + String policyScope = scopeAndName[0]; + String policyName = scopeAndName[1]; + policy.setScope(policyScope); + policy.setPolicyName(policyName); + policy.setCreatedBy(AUDIT_USER); + policy.setModifiedBy(AUDIT_USER); + + String newScope = policyScope.replace(".", File.separator); + String newName = FilenameUtils.removeExtension(policyName); + int version = 1; + try{ + //we want the last index +1 because we don't want the dot + version = Integer.parseInt(newName.substring(newName.lastIndexOf(".")+1)); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not get the policy version number from "+newName); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get the policy version number from "+newName); + } + newName = newScope + File.separator + newName.substring(0, newName.lastIndexOf(".")); + + Query query = em.createNamedQuery("PolicyVersion.findByPolicyName"); + query.setParameter("pname", newName); + + List result = query.getResultList(); + PolicyVersion versionEntity = null; + + if (!result.isEmpty()) { + logger.info("Result is not empty"); + versionEntity = (PolicyVersion) result.get(0); + int highestVersion = Math.max(versionEntity.getHigherVersion(),version); + versionEntity.setHigherVersion(highestVersion); + versionEntity.setActiveVersion(highestVersion); + }else{ + logger.info("result is empty"); + Calendar calendar = Calendar.getInstance(); + Timestamp createdDate = new Timestamp(calendar.getTime().getTime()); + + versionEntity = new PolicyVersion(); + em.persist(versionEntity); + versionEntity.setPolicyName(newName); + versionEntity.setHigherVersion(version); + versionEntity.setActiveVersion(version); + versionEntity.setCreatedBy(AUDIT_USER); + versionEntity.setModifiedBy(AUDIT_USER); + versionEntity.setCreatedDate(createdDate); + versionEntity.setModifiedDate(createdDate); + } + + + try { + String policyContent = new String(Files.readAllBytes(path)); + policy.setDescription(getElementFromXMLString("/Description", policyContent)); + policy.setPolicyData(policyContent); + } catch (IOException e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error settingPolicyData: " + e1.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData"); + em.getTransaction().rollback(); + em.close(); + return; + } + + if((scopeAndName[2].equalsIgnoreCase("Config"))){ + String scopeName = scopeAndName[0] + "." + scopeAndName[1]; + Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]); + try { + String content = new String(Files.readAllBytes(subFilePath)); + String configName = subFilePath.getFileName().toString(); + ConfigurationDataEntity configData = new ConfigurationDataEntity(); + em.persist(configData); + configData.setConfigurationName(subFilePath.getFileName().toString()); + configData.setConfigBody(content); + configData.setConfigType(getPolicySubType(configName)); + configData.setCreatedBy(AUDIT_USER); + configData.setModifiedBy(AUDIT_USER); + policy.setConfigurationData(configData); + + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error for Config policy: " + e.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Config policy"); + em.getTransaction().rollback(); + em.close(); + return; + } + }else if(scopeAndName[2].equalsIgnoreCase("Action")){ + String scopeName = scopeAndName[0] + "." + scopeAndName[1]; + Path subFilePath = getPolicySubFile(scopeName, scopeAndName[2]); + try { + String content = new String(Files.readAllBytes(subFilePath)); + ActionBodyEntity actionBody = new ActionBodyEntity(); + em.persist(actionBody); + actionBody.setActionBodyName(subFilePath.getFileName().toString()); + actionBody.setActionBody(content); + actionBody.setCreatedBy(AUDIT_USER); + actionBody.setModifiedBy(AUDIT_USER); + policy.setActionBodyEntity(actionBody); + + } catch (Exception e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error for Action policy: " + e.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "convertFileToDBEntry error for Action policy"); + em.getTransaction().rollback(); + em.close(); + return; + } + } + logger.debug("convertFileToDBEntry commit transaction"); + em.getTransaction().commit(); + em.close(); + } + + private void deleteAllPolicyTables(){ + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + Query deletePolicyEntityTableUpdate = em.createNamedQuery("PolicyEntity.deleteAll"); + Query deleteActionBodyEntityTableUpdate = em.createNamedQuery("ActionBodyEntity.deleteAll"); + Query deleteConfigurationDataEntityTableUpdate = em.createNamedQuery("ConfigurationDataEntity.deleteAll"); + Query deletePolicyVersionEntityTableUpdate = em.createNamedQuery("PolicyVersion.deleteAll"); + deletePolicyEntityTableUpdate.executeUpdate(); + deleteActionBodyEntityTableUpdate.executeUpdate(); + deleteConfigurationDataEntityTableUpdate.executeUpdate(); + deletePolicyVersionEntityTableUpdate.executeUpdate(); + em.getTransaction().commit(); + em.close(); + + } + + public void auditLocalDatabase(PAPPolicyEngine papEngine2){ + logger.debug("PolicyDBDao.auditLocalDatabase() is called"); + Path webappsPath = Paths.get(buildPolicyDirectory()); + try{ + deleteAllGroupTables(); + deleteAllPolicyTables(); + Files.createDirectories(webappsPath); + Files.walk(webappsPath).filter(Files::isRegularFile).forEach(this::convertFileToDBEntry); + auditGroups(papEngine2); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("auditLocalDatabase() error: " + e.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "auditLocalDatabase() error"); + e.printStackTrace(); + } + } + + /** + * Audits and loads the local file system to match the database version. + */ + @SuppressWarnings("unchecked") + public void auditLocalFileSystem(){ + logger.debug("PolicyDBDau.auditLocalFileSystem() is called"); + + Path webappsPath = Paths.get(buildPolicyDirectory()); + Path configFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Config"); + Path actionFilesPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), "Action"); + try { + Files.createDirectories(configFilesPath); + Files.createDirectories(actionFilesPath); + FileUtils.cleanDirectory(actionFilesPath.toFile()); + FileUtils.cleanDirectory(configFilesPath.toFile()); + if (webappsPath.toFile().exists()){ + FileUtils.cleanDirectory(webappsPath.toFile()); + } + Path repoWithScope = Paths.get(webappsPath.toString(), XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DOMAIN)); + Files.createDirectories(repoWithScope); + } catch (IOException e2) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Error occurred while creating / clearing Config and Policy filesystem directories", e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Error occurred while creating / clearing Config and Policy filesystem directories"); + } + + List policyEntityList; + try{ + EntityManager em = emf.createEntityManager(); + Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findAllByDeletedFlag"); + getPolicyEntitiesQuery.setParameter("deleted", false); + policyEntityList = getPolicyEntitiesQuery.getResultList(); + } catch(Exception e){ + policyEntityList = new LinkedList(); + } + + for (PolicyEntity policy: policyEntityList){ + String name = ""; + try { + if (!policy.isDeleted()){ + name = policy.getPolicyName(); + String scope = policy.getScope(); + + scope = scope.replace(".", "//"); + if (policy.getConfigurationData()!=null){ + writePolicySubFile(policy, "Config"); + } + else if(policy.getActionBodyEntity()!=null){ + writePolicySubFile(policy, "Action"); + } + + + Path fileLocation = Paths.get(webappsPath.toString(), scope); + + Files.createDirectories(fileLocation); + Path newPath = Paths.get(fileLocation.toString(), name); + Object policyData = XACMLPolicyScanner.readPolicy(IOUtils.toInputStream(policy.getPolicyData())); + XACMLPolicyWriter.writePolicyFile(newPath, (PolicyType) policyData); + } + } catch (Exception e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Error occurred while creating Policy File: " + name, e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Error occurred while creating Policy File: " + name); + } + } + createGroupsFromDatabase(); + } + + public void deleteAllGroupTables(){ + logger.debug("PolicyDBDao.deleteAllGroupTables() called"); + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll"); + deletePdpEntityEntityTableUpdate.executeUpdate(); + + Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll"); + deleteGroupEntityTableUpdate.executeUpdate(); + + em.getTransaction().commit(); + em.close(); + } + + @SuppressWarnings("unchecked") + public void auditGroups(PAPPolicyEngine papEngine2){ + logger.debug("PolicyDBDao.auditGroups() called"); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + final String AUDIT_STR = "Audit"; + try{ + + Set groups = papEngine2.getEcompPDPGroups(); + + for (EcompPDPGroup grp : groups){ + try{ + GroupEntity groupEntity = new GroupEntity(); + em.persist(groupEntity); + groupEntity.setGroupName(grp.getName()); + groupEntity.setDescription(grp.getDescription()); + groupEntity.setDefaultGroup(grp.isDefaultGroup()); + groupEntity.setCreatedBy(AUDIT_STR); + groupEntity.setGroupId(createNewPDPGroupId(grp.getId())); + groupEntity.setModifiedBy(AUDIT_STR); + Set pdps = grp.getEcompPdps(); + + for(EcompPDP pdp : pdps){ + PdpEntity pdpEntity = new PdpEntity(); + em.persist(pdpEntity); + pdpEntity.setGroup(groupEntity); + pdpEntity.setJmxPort(pdp.getJmxPort()); + pdpEntity.setPdpId(pdp.getId()); + pdpEntity.setPdpName(pdp.getName()); + pdpEntity.setModifiedBy(AUDIT_STR); + pdpEntity.setCreatedBy(AUDIT_STR); + + } + + Set policies = grp.getPolicies(); + + for(PDPPolicy policy : policies){ + try{ + String[] stringArray = getNameScopeAndVersionFromPdpPolicy(policy.getId()); + List policyEntityList; + Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope"); + getPolicyEntitiesQuery.setParameter("name", stringArray[0]); + getPolicyEntitiesQuery.setParameter("scope", stringArray[1]); + + policyEntityList = getPolicyEntitiesQuery.getResultList(); + PolicyEntity policyEntity = null; + if(policyEntityList.size() < 1){ + policyEntity = addPolicyThatOnlyExistsInPdpGroup(policy.getId(),Paths.get("pdps",grp.getId(),policy.getId()),em); + } else { + policyEntity = policyEntityList.get(0); + } + if(policyEntity != null){ + groupEntity.addPolicyToGroup(policyEntity); + } + }catch(Exception e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("ERROR: " + e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Exception auditGroups inner catch"); + } + } + }catch(Exception e1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("ERROR: " + e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "Exception auditGroups middle catch"); + } + } + }catch(Exception e){ + em.getTransaction().rollback(); + //TODO:EELF Cleanup - Remove logger + //logger.error("ERROR: " + e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception auditGroups outer catch"); + em.close(); + return; + } + + em.getTransaction().commit(); + em.close(); + + } + + private PolicyEntity addPolicyThatOnlyExistsInPdpGroup(String polId, Path path,EntityManager em){ + String filename = path.getFileName().toString(); + if (filename.contains(".svnignore")){ + return null; + } + + String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(polId); + + if(scopeAndName == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + polId.toString() + " is null!"); + PolicyLogger.error("convertFileToDBEntry error: getScopeAndNameAndType(" + polId.toString() + " is null!"); + return null; + } + + + PolicyEntity policy = new PolicyEntity(); + em.persist(policy); + String policyScope = scopeAndName[1]; + String policyName = scopeAndName[0]; + policy.setScope(policyScope); + policy.setPolicyName(policyName); + policy.setCreatedBy(AUDIT_USER); + policy.setModifiedBy(AUDIT_USER); + policy.setDeleted(true); + + try { + String policyContent = new String(Files.readAllBytes(path)); + policy.setDescription(getElementFromXMLString("/Description", policyContent)); + policy.setPolicyData(policyContent); + em.flush(); + //em.getTransaction().commit(); + } catch (IOException e1) { + // TODO Auto-generated catch block + //TODO:EELF Cleanup - Remove logger + //logger.error("convertFileToDBEntry error settingPolicyData: " + e1.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "convertFileToDBEntry error settingPolicyData"); + return null; + } + //em.close(); + return policy; + } + + private String getConfigFile(String filename, String scope, PolicyRestAdapter policy){ + if(policy == null){ + return getConfigFile(filename, scope, (String)null); + } + return getConfigFile(filename, scope, policy.getConfigType()); + } + //copied from ConfigPolicy.java and modified + // Here we are adding the extension for the configurations file based on the + // config type selection for saving. + private String getConfigFile(String filename, String scope, String configType) { + logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile("+filename+", "+scope+", "+configType+") called"); + filename = FilenameUtils.removeExtension(filename); +// if (filename.endsWith(".xml")) { +// filename = filename.substring(0, filename.length() - 4); +// } + String id = configType; + + if (id != null) { + if (id.equals(ConfigPolicy.JSON_CONFIG) || id.contains("Firewall")) { + filename = filename + ".json"; + } + if (id.equals(ConfigPolicy.XML_CONFIG)) { + filename = filename + ".xml"; + } + if (id.equals(ConfigPolicy.PROPERTIES_CONFIG)) { + filename = filename + ".properties"; + } + if (id.equals(ConfigPolicy.OTHER_CONFIG)) { + filename = filename + ".txt"; + } + } + return scope + "." + filename; + } + + /** + * Constructs the file name of a policy. + * @param policy The name of a policy (ex: mypolicy1) + * @return The file name of the policy (ex: Config_mypolicy1.xml) + * @deprecated + */ + @SuppressWarnings("unused") + private String getName(PolicyRestAdapter policy){ + logger.debug("getName(PolicyRestAdapter policy) as getName("+policy+") called"); + String namePrefix = ""; + if(policy.getPolicyType().contains("Config")){ + namePrefix = namePrefix.concat(policy.getPolicyType()); + if(policy.getConfigType().contains("Firewall")){ + namePrefix = namePrefix.concat("_FW"); + } + } + String concats = namePrefix + "_" +policy.getPolicyName() + ".xml"; + return concats; + } + + private String stripPolicyName(String policyFileName){ + String policyName = policyFileName; + try{ + policyName = policyName.substring(policyName.indexOf('_')+1); + policyName = removeFileExtension(policyName); + }catch(Exception e){ + throw new IllegalArgumentException("Could not get name out of policy file name: "+policyName); + } + return policyName; + } + //FIXME error check, logs + private String[] getNameScopeAndVersionFromPdpPolicy(String fileName){ + String[] splitByDots = fileName.split("\\."); + if(splitByDots.length < 3){ + //throw something + return null; + } + String policyName = splitByDots[splitByDots.length-3]; + String version = splitByDots[splitByDots.length-2]; + //policy names now include version + policyName += "."+version +".xml"; + String scope = ""; + for(int i=0;i 0){ + scope = scope.substring(1); + } + String[] returnArray = new String[3]; + returnArray[0] = policyName; + returnArray[2] = version; + returnArray[1] = scope; + return returnArray; + } + + /** + * Constructs the complete repository path based on the properties files + * @return The repository path + */ + public static String getGitPath(){ + logger.debug("getGitPath() as getGitPath() called"); + Path workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WORKSPACE), "admin"); + Path repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_REPOSITORY)); + Path gitPath = Paths.get(workspacePath.toString(), repositoryPath.getFileName().toString()); + logger.debug("after gitPath: " + gitPath); + return gitPath.toString(); + } + + //copied from StdEngine.java + public static String createNewPDPGroupId(String name) { + String id = name; + // replace "bad" characters with sequences that will be ok for file names and properties keys. + id = id.replace(" ", "_sp_"); + id = id.replace("\t", "_tab_"); + id = id.replace("\\", "_bksl_"); + id = id.replace("/", "_sl_"); + id = id.replace(":", "_col_"); + id = id.replace("*", "_ast_"); + id = id.replace("?", "_q_"); + id = id.replace("\"", "_quo_"); + id = id.replace("<", "_lt_"); + id = id.replace(">", "_gt_"); + id = id.replace("|", "_bar_"); + id = id.replace("=", "_eq_"); + id = id.replace(",", "_com_"); + id = id.replace(";", "_scom_"); + + return id; + } + + /** + * Checks if any of the given strings are empty or null + * @param strings One or more Strings (or nulls) to check if they are null or empty + * @return true if one or more of the given strings are empty or null + */ + private static boolean isNullOrEmpty(String... strings){ + for(String s : strings){ + if(!(s instanceof String)){ + return true; + } + if(s.equals("")){ + return true; + } + } + return false; + } + + /** + * Computes the scope, name, and type of a policy based on its file path + * @param path The file path of the policy (including the xml policy file) + * @return A string array of size 3. 1: the scope of the policy 2: the name of the policy (Config_mypol.xml) 3: the type (Config). Or, null if the path can not be parsed. + */ + private static String[] getScopeAndNameAndType(String path){ + logger.debug("getScopeAndNameAndType(String path) as getScopeAndNameAndType("+path+") called"); + if(path == null){ + + } + String gitPath = getGitPath(); + + ArrayList gitPathParts = new ArrayList(); + Iterator gitPathIterator = Paths.get(gitPath).iterator(); + while(gitPathIterator.hasNext()){ + gitPathParts.add(gitPathIterator.next().toString()); + } + for(int i=0;i= path.length()){ + logger.debug("gitPath length(): " + gitPath.length() + ">= path.length(): " + path.length() + ". Returning null"); + return null; + } + String scopeAndName = path.substring(path.indexOf(gitPath)+gitPath.length()); + + logger.debug("scopeAndName: " + scopeAndName); + String policyType = null; + String[] policyTypes = {"Config_","Action_","Decision_"}; + for(String pType : policyTypes){ + if(scopeAndName.contains(pType)){ + policyType = pType; + } + } + if(policyType == null){ + return null; + } + String scope = scopeAndName.substring(0,scopeAndName.indexOf(policyType)); + String name = scopeAndName.substring(scopeAndName.indexOf(policyType), scopeAndName.length()); + scope = scope.replace('\\', '.'); + scope = scope.replace('/', '.'); + if(scope.length()<1){ + return null; + } + if(scope.charAt(0) == '.'){ + if(scope.length() < 2){ + logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2. " + "| scope.charAt(0)==."); + return null; + } + scope = scope.substring(1); + } + if(scope.charAt(scope.length()-1) == '.'){ + if(scope.length() < 2){ + logger.debug("getScopeAndNameAndType error: " + scope.length() + " < 2" + "| scope.charAt(scope.length()-1)==."); + return null; + } + scope = scope.substring(0,scope.length()-1); + } + if(name.length()<1){ + logger.debug("getScopeAndNameAndType error: name.length()<1"); + return null; + } + if(name.charAt(0) == '.'){ + if(name.length() < 2){ + logger.debug("getScopeAndNameAndType error: " + name.length() + " < 2. " + "| scope.charAt(0)==."); + return null; + } + name = name.substring(1); + } + String[] returnArray = new String[3]; + returnArray[0] = scope; + returnArray[1] = name; + //remove the underscore and return it + returnArray[2] = policyType.substring(0, policyType.length()-1); + return returnArray; + } + + + private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction { + private EntityManager em; + private final Object emLock = new Object(); + long policyId; + long groupId; + long pdpId; + String newGroupId; + private boolean operationRun = false; + private final Thread transactionTimer; + + private PolicyDBDaoTransactionInstance(){ + //call the constructor with arguments + this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)), + Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT))); + } + //timeout is how long the transaction can sit before rolling back + //wait time is how long to wait for the transaction to start before throwing an exception + private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime){ + if(logger.isDebugEnabled()){ + logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:" + + "\n transactionTimeout = " + transactionTimeout + + "\n transactionWaitTime = " + transactionWaitTime + "\n\n"); + } + this.em = emf.createEntityManager(); + policyId = -1; + groupId = -1; + pdpId = -1; + newGroupId = null; + synchronized(emLock){ + try{ + startTransactionSynced(this.em,transactionWaitTime); + } catch(Exception e){ + throw new PersistenceException("Could not lock transaction within "+transactionWaitTime+" milliseconds"); + } + } + class TransactionTimer implements Runnable { + + private int sleepTime; + public TransactionTimer(int timeout){ + this.sleepTime = timeout; + } + @Override + public void run() { + if(logger.isDebugEnabled()){ + Date date= new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - SLEEPING: " + + "\n sleepTime (ms) = " + sleepTime + + "\n TimeStamp = " + date.getTime() + + "\n\n"); + } + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + //probably, the transaction was completed, the last thing we want to do is roll back + if(logger.isDebugEnabled()){ + Date date= new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: " + + "\n TimeStamp = " + date.getTime() + + "\n\n"); + } + return; + } + if(logger.isDebugEnabled()){ + Date date= new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: " + + "\n TimeStamp = " + date.getTime() + + "\n\n"); + } + rollbackTransaction(); + } + + } + + transactionTimer = new Thread(new TransactionTimer(transactionTimeout),"transactionTimerThread"); + transactionTimer.start(); + + + } + + private void checkBeforeOperationRun(){ + checkBeforeOperationRun(false); + } + private void checkBeforeOperationRun(boolean justCheckOpen){ + if(!isTransactionOpen()){ + //TODO:EELF Cleanup - Remove logger + //logger.error("There is no transaction currently open"); + PolicyLogger.error("There is no transaction currently open"); + throw new IllegalStateException("There is no transaction currently open"); + } + if(operationRun && !justCheckOpen){ + //TODO:EELF Cleanup - Remove logger + //logger.error("An operation has already been performed and the current transaction should be committed"); + PolicyLogger.error("An operation has already been performed and the current transaction should be committed"); + throw new IllegalStateException("An operation has already been performed and the current transaction should be committed"); + } + operationRun = true; + } + @Override + public void commitTransaction() { + synchronized(emLock){ + logger.debug("commitTransaction() as commitTransaction() called"); + if(!isTransactionOpen()){ + logger.warn("There is no open transaction to commit"); + //throw new IllegalStateException("There is no open transaction to commit"); + try{ + em.close(); + } catch(Exception e){ + e.printStackTrace(); + } + return; + } + try{ + em.getTransaction().commit(); + } catch(RollbackException e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught RollbackException on em.getTransaction().commit()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught RollbackException on em.getTransaction().commit()"); + throw new PersistenceException("The commit failed. Message:\n"+e.getMessage()); + } + em.close(); + //FIXME need to revisit + if(policyId >= 0){ + + if(newGroupId != null){ + try{ + notifyOthers(policyId,POLICY_NOTIFICATION,newGroupId); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+","+newGroupId+")"); + } + } else { + try{ + notifyOthers(policyId,POLICY_NOTIFICATION); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+policyId+","+POLICY_NOTIFICATION+")"); + } + } + } + if(groupId >= 0){ + //we don't want commit to fail just because this does + if(newGroupId != null){ + try{ + notifyOthers(groupId,GROUP_NOTIFICATION,newGroupId); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+","+newGroupId+")"); + } + } else { + try{ + notifyOthers(groupId,GROUP_NOTIFICATION); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+groupId+","+GROUP_NOTIFICATION+")"); + } + } + } + if(pdpId >= 0){ + //we don't want commit to fail just because this does + try{ + notifyOthers(pdpId,PDP_NOTIFICATION); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on notifyOthers("+pdpId+","+PDP_NOTIFICATION+")"); + } + } + } + if(transactionTimer instanceof Thread){ + transactionTimer.interrupt(); + } + } + + @Override + public void rollbackTransaction() { + logger.debug("rollbackTransaction() as rollbackTransaction() called"); + synchronized(emLock){ + if(isTransactionOpen()){ + + try{ + em.getTransaction().rollback(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not rollback transaction"); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not rollback transaction"); + } + try{ + em.close(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not close EntityManager"); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not close EntityManager"); + } + + } else { + try{ + em.close(); + }catch(Exception e){ + logger.warn("Could not close already closed transaction"); + } + } + + } + if(transactionTimer instanceof Thread){ + transactionTimer.interrupt(); + } + + + } + + private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) { + logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, String policyDataString) as createPolicy("+policy+", "+username+", "+policyScope+", "+policyName+", "+policyDataString+") called"); + synchronized(emLock){ + checkBeforeOperationRun(); + //em.getTransaction().begin(); + //FIXME if the policy is already found but deleted, when we update it should we reset the created by and version number? + Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"); + createPolicyQuery.setParameter("scope", policyScope); + createPolicyQuery.setParameter("policyName", policyName); + //createPolicyQuery.setParameter("deleted", false); + List createPolicyQueryList = createPolicyQuery.getResultList(); + PolicyEntity newPolicyEntity; + boolean update; + if(createPolicyQueryList.size() < 1){ + newPolicyEntity = new PolicyEntity(); + update = false; + } else if(createPolicyQueryList.size() > 1){ + //something went wrong + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + } else { + newPolicyEntity = (PolicyEntity)createPolicyQueryList.get(0); + update = true; + } + + ActionBodyEntity newActionBodyEntity = null; + if(policy.getPolicyType().equals("Action")){ + boolean abupdate = false; + if(newPolicyEntity.getActionBodyEntity() == null){ + newActionBodyEntity = new ActionBodyEntity(); + }else{ + newActionBodyEntity = em.find(ActionBodyEntity.class, newPolicyEntity.getActionBodyEntity().getActionBodyId()); + abupdate = true; + } + + if(newActionBodyEntity != null){ + if(!abupdate){ + em.persist(newActionBodyEntity); + } + //build the file path + //trim the .xml off the end + String policyNameClean = FilenameUtils.removeExtension(policyName); + String actionBodyName = policyScope + "." + policyNameClean + ".json"; + Path actionBodyPath = Paths.get(Webapps.getActionHome(), actionBodyName); + if(logger.isDebugEnabled()){ + logger.debug("\nPolicyDBDao.createPolicy" + + "\n actionBodyPath = " + actionBodyPath); + } + //get the action body + String actionBodyString = null; + String actionBodyPathStr = null; + InputStream fileContentStream = null; + + if (Files.exists(actionBodyPath)) { + try { + actionBodyPathStr = (actionBodyPath != null ? actionBodyPath.toString() : null); + fileContentStream = new FileInputStream(actionBodyPathStr); + actionBodyString = IOUtils.toString(fileContentStream); + if(logger.isDebugEnabled()){ + logger.debug("\nPolicyDBDao.createPolicy" + + "\n actionBodyPathStr = " + actionBodyPathStr + + "\n actionBodyString = " + actionBodyString); + } + } catch (FileNotFoundException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new actionBodyPathStr FileInputStream("+actionBodyPathStr+")"); + throw new IllegalArgumentException("The actionBodyPathStr file path " + actionBodyPathStr + " does not exist" + + "\nEXCEPTION: " + e); + } catch(IOException e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")",e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on actionBodyPath newIOUtils.toString("+fileContentStream+")"); + throw new IllegalArgumentException("The actionBodyPath file path cannot be read" + fileContentStream + + "\nEXCEPTION: " + e2); + } finally { + IOUtils.closeQuietly(fileContentStream); + } + + if(actionBodyString == null){ + throw new IllegalArgumentException("The file path (" + actionBodyPathStr + ") cannot be read"); + } + + } else { + actionBodyString = "{}"; + } + + newActionBodyEntity.setActionBody(actionBodyString); + newActionBodyEntity.setActionBodyName(actionBodyName); + newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()"); + newActionBodyEntity.setDeleted(false); + if(!abupdate){ + newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()"); + } + if(logger.isDebugEnabled()){ + logger.debug("\nPolicyDBDao.createPolicy" + + "\n newActionBodyEntity.getActionBody() = " + newActionBodyEntity.getActionBody() + + "\n newActionBodyEntity.getActionBodyName() = " + newActionBodyEntity.getActionBodyName() + + "\n newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy() + + "\n newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy() + + "\n newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted() + + "\n FLUSHING to DB"); + } + //push the actionBodyEntity to the DB + em.flush(); + }else{ + //newActionBodyEntity == null + //We have a actionBody in the policy but we found no actionBody in the DB + String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an " + + "actionBody, but it could not be found in the DB for update." + + "\n policyScope = " + policyScope + + "\n policyName = " + policyName + "\n\n"; + //TODO:EELF Cleanup - Remove logger + //logger.error(msg); + PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it could not be found in the DB for update: policyName = " + policyName); + throw new IllegalArgumentException(msg); + } + } + + ConfigurationDataEntity newConfigurationDataEntity; + if(policy.getPolicyType().equals("Config")){ + boolean configUpdate; + if(newPolicyEntity.getConfigurationData() == null){ + newConfigurationDataEntity = new ConfigurationDataEntity(); + configUpdate = false; + } else { + newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, newPolicyEntity.getConfigurationData().getConfigurationDataId()); + configUpdate = true; + } + + if(newConfigurationDataEntity != null){ + if(!configUpdate){ + em.persist(newConfigurationDataEntity); + } + //ConfigPolicy configPolicy = (ConfigPolicy)policy; + if(!stringEquals(newConfigurationDataEntity.getConfigurationName(),getConfigFile(policyName,policyScope,policy))){ + newConfigurationDataEntity.setConfigurationName(getConfigFile(policyName,policyScope,policy)); + } + if(newConfigurationDataEntity.getConfigType() == null || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())){ + newConfigurationDataEntity.setConfigType(policy.getConfigType()); + } + if(!configUpdate){ + newConfigurationDataEntity.setCreatedBy(username); + } + if(newConfigurationDataEntity.getModifiedBy() == null || !newConfigurationDataEntity.getModifiedBy().equals(username)){ + newConfigurationDataEntity.setModifiedBy(username); + } + if(newConfigurationDataEntity.getDescription() == null || !newConfigurationDataEntity.getDescription().equals("")){ + newConfigurationDataEntity.setDescription(""); + } + if(newConfigurationDataEntity.getConfigBody() == null || newConfigurationDataEntity.getConfigBody().isEmpty() || + (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))){ + //hopefully one of these won't be null + if(policy.getConfigBodyData() == null){ + newConfigurationDataEntity.setConfigBody(policy.getJsonBody()); + }else{ + newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData()); + } + } + if(newConfigurationDataEntity.isDeleted() == true){ + newConfigurationDataEntity.setDeleted(false); + } + + em.flush(); + }else{//newConfigurationDataEntity == null + //We have a configurationData body in the policy but we found no configurationData body + //in the DB + String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a " + + "configurationData body, but it could not be found in the DB for update." + + "\n policyScope = " + policyScope + + "\n policyName = " + policyName + "\n\n"; + //TODO:EELF Cleanup - Remove logger + //logger.error(msg); + PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, but it could not be found in the DB for update: policyName = " + policyName); + throw new IllegalArgumentException(msg); + } + + } else { + newConfigurationDataEntity = null; + } + if(!update){ + em.persist(newPolicyEntity); + } + + policyId = newPolicyEntity.getPolicyId(); + //policy version is now part of policy name + /* + if(update){ + try{ + String versionString = evaluateXPath("Policy/@Version", policyDataString); + int versionNum = Integer.parseInt(versionString); + if(versionNum < 1){ + throw new NumberFormatException(); + } + newPolicyEntity.setPolicyVersion(versionNum); + } catch(Exception e){ + if(newPolicyEntity.isDeleted()){ + newPolicyEntity.resetPolicyVersion(); + } else { + newPolicyEntity.advancePolicyVersion(); + } + } + + + } + */ + if(!stringEquals(newPolicyEntity.getPolicyName(),policyName)){ + newPolicyEntity.setPolicyName(policyName); + } + if(!stringEquals(newPolicyEntity.getCreatedBy(),username)){ + newPolicyEntity.setCreatedBy(username); + } + if(!stringEquals(newPolicyEntity.getDescription(),policy.getPolicyDescription())){ + newPolicyEntity.setDescription(policy.getPolicyDescription()); + } + if(!stringEquals(newPolicyEntity.getModifiedBy(),username)){ + newPolicyEntity.setModifiedBy(username); + } + if(!stringEquals(newPolicyEntity.getPolicyData(),policyDataString)){ + newPolicyEntity.setPolicyData(policyDataString); + } + if(!stringEquals(newPolicyEntity.getScope(),policyScope)){ + newPolicyEntity.setScope(policyScope); + } + if(newPolicyEntity.isDeleted() == true){ + newPolicyEntity.setDeleted(false); + } + newPolicyEntity.setConfigurationData(newConfigurationDataEntity); + newPolicyEntity.setActionBodyEntity(newActionBodyEntity); + + + em.flush(); + this.policyId = newPolicyEntity.getPolicyId(); + } + + return; + } + + @SuppressWarnings("unused") + public PolicyEntity getPolicy(int policyID){ + return getPolicy(policyID,null,null); + } + public PolicyEntity getPolicy(String policyName,String scope){ + return getPolicy(-1,policyName,scope); + } + private PolicyEntity getPolicy(int policyID, String policyName,String scope){ + logger.debug("getPolicy(int policyId, String policyName) as getPolicy("+policyID+","+policyName+") called"); + if(policyID < 0 && isNullOrEmpty(policyName,scope)){ + throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank"); + } + + synchronized(emLock){ + checkBeforeOperationRun(true); + //check if group exists + String policyId; + Query policyQuery; + if(!isNullOrEmpty(policyName,scope)){ + policyId = policyName; + policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope"); + policyQuery.setParameter("name", policyId); + policyQuery.setParameter("scope", scope); + } else{ + policyId = String.valueOf(policyID); + policyQuery = em.createNamedQuery("PolicyEntity.FindById"); + policyQuery.setParameter("id", policyId); + } + List policyQueryList; + try{ + policyQueryList = policyQuery.getResultList(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get policy with policyQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get policy with policyQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get policy "+policyId); + } + if(policyQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Policy does not exist with id "+policyId); + PolicyLogger.error("Policy does not exist with id "+policyId); + throw new PersistenceException("Group policy is being added to does not exist with id "+policyId); + } else if(policyQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one policy with the id "+policyId+" were found in the database"); + PolicyLogger.error("Somehow, more than one policy with the id "+policyId+" were found in the database"); + throw new PersistenceException("Somehow, more than one policy with the id "+policyId+" were found in the database"); + } + return (PolicyEntity)policyQueryList.get(0); + } + } + + @Override + public void renamePolicy(String oldPath, String newPath,String username){ + String[] oldPolicy = getScopeAndNameAndType(oldPath); + String[] newPolicy = getScopeAndNameAndType(newPath); + if(oldPolicy == null || newPolicy == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: " + //+oldPath+", "+newPath); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: " + +oldPath+", "+newPath); + throw new IllegalArgumentException("Could not parse one or more of the path names"); + } + synchronized (emLock) { + checkBeforeOperationRun(); + + PolicyEntity existingPolicy; + boolean existingPolicyDeleted = false; + List groups = null; + try{ + existingPolicy = getPolicy(newPolicy[1],newPolicy[0]); + } catch(Exception e){ + existingPolicy = null; + } + if(existingPolicy != null && !existingPolicy.isDeleted()){ + logger.error("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy); + throw new IllegalArgumentException("The policy named "+existingPolicy.getPolicyName()+" already exists, cannot rename policy: "+newPolicy); + } else if(existingPolicy != null && existingPolicy.isDeleted()){ + try{ + Query getGroups = em.createQuery("SELECT g FROM GroupEntity g JOIN g.policies p WHERE p.policyId=:pid"); + + getGroups.setParameter("pid", existingPolicy.getPolicyId()); + groups = getGroups.getResultList(); + }catch(Exception e){ + groups = new LinkedList(); + } + for(Object o : groups){ + + GroupEntity group = (GroupEntity)o; + group.removePolicyFromGroup(existingPolicy); + } + try{ + em.flush(); + }catch(Exception e){ + logger.error("Error while removing the policy from groups: "+existingPolicy.getPolicyName()); + } + try{ + em.remove(existingPolicy); + em.flush(); + }catch(Exception e){ + logger.error("Could not remove the existing deleted policy: "+existingPolicy.getPolicyName()); + } + existingPolicyDeleted = true; + //create the new policy + //for each of the groups, add the new policy + } + + PolicyEntity policyToRename; + try{ + policyToRename = getPolicy(oldPolicy[1],oldPolicy[0]); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not get policy record to rename: " + //+oldPolicy[1],e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to rename: " + +oldPolicy[1]); + throw new PersistenceException("Could not get policy record to rename"); + } + String policyDataString = null; + InputStream fileContentStream = null; + String policyFilePath = Paths.get(oldPath).toAbsolutePath().toString(); + //I want to try the old path first, then if it doesn't work, try the new path + for(int i=0;i<2;i++){ + try { + fileContentStream = new FileInputStream(policyFilePath); + policyDataString = IOUtils.toString(fileContentStream); + } catch (FileNotFoundException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught FileNotFoundException on new FileInputStream("+policyFilePath+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+policyFilePath+")"); + //if we can't find the oldPath, we'll try the new path + if(i == 0){ + policyFilePath = Paths.get(newPath).toAbsolutePath().toString(); + continue; + } + throw new IllegalArgumentException("The file path does not exist"); + } catch(IOException e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught IOException on newIOUtils.toString("+fileContentStream+")",e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")"); + throw new IllegalArgumentException("The file path cannot be read"); + } finally { + IOUtils.closeQuietly(fileContentStream); + } + if(policyDataString == null){ + throw new IllegalArgumentException("The file path cannot be read"); + } + //escape the loop + i=2; + } + policyToRename.setPolicyName(newPolicy[1]); + policyToRename.setPolicyData(policyDataString); + policyToRename.setScope(newPolicy[0]); + policyToRename.setModifiedBy(username); + if(policyToRename.getConfigurationData() != null){ + //String configType = getPolicySubType(policyToRename.getConfigurationData().getConfigurationName()); + String configType = policyToRename.getConfigurationData().getConfigType(); + policyToRename.getConfigurationData().setConfigurationName(getConfigFile(newPolicy[1], newPolicy[0], configType)); + policyToRename.getConfigurationData().setModifiedBy(username); + } + if(policyToRename.getActionBodyEntity() != null){ + String newActionName = newPolicy[0]+"."+removeFileExtension(newPolicy[1])+".json"; + policyToRename.getActionBodyEntity().setActionBodyName(newActionName); + policyToRename.getActionBodyEntity().setModifiedBy(username); + } + if(existingPolicyDeleted){ + for(Object o : groups){ + + GroupEntity group = (GroupEntity)o; + group.addPolicyToGroup(policyToRename); + } + } + em.flush(); + this.policyId = policyToRename.getPolicyId(); + this.newGroupId = oldPath; + } + } + + @Override + public GroupEntity getGroup(long groupKey){ + logger.debug("getGroup(int groupKey) as getGroup("+groupKey+") called"); + if(groupKey < 0){ + throw new IllegalArgumentException("groupKey must be at least 0"); + } + synchronized(emLock){ + checkBeforeOperationRun(true); + //check if group exists + Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey"); + groupQuery.setParameter("groupKey", groupKey); + List groupQueryList; + try{ + groupQueryList = groupQuery.getResultList(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get group with groupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get group "+groupKey); + } + if(groupQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Group does not exist with groupKey "+groupKey); + PolicyLogger.error("Group does not exist with groupKey "+groupKey); + throw new PersistenceException("Group does not exist with groupKey "+groupKey); + } else if(groupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database"); + PolicyLogger.error("Somehow, more than one group with the groupKey "+groupKey+" were found in the database"); + throw new PersistenceException("Somehow, more than one group with the groupKey "+groupKey+" were found in the database"); + } + return (GroupEntity)groupQueryList.get(0); + } + } + + @Override + public GroupEntity getGroup(String groupId){ + logger.debug("getGroup(String groupId) as getGroup("+groupId+") called"); + if(isNullOrEmpty(groupId)){ + throw new IllegalArgumentException("groupId must not be null or empty"); + } + synchronized(emLock){ + checkBeforeOperationRun(true); + //check if group exists + Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId"); + groupQuery.setParameter("groupId", groupId); + List groupQueryList; + try{ + groupQueryList = groupQuery.getResultList(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get group with groupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group with groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get group "+groupId); + } + if(groupQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Group does not exist with id "+groupId); + PolicyLogger.error("Group does not exist with id "+groupId); + throw new PersistenceException("Group does not exist with id "+groupId); + } else if(groupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the id "+groupId+" were found in the database"); + PolicyLogger.error("Somehow, more than one group with the id "+groupId+" were found in the database"); + throw new PersistenceException("Somehow, more than one group with the id "+groupId+" were found in the database"); + } + return (GroupEntity)groupQueryList.get(0); + } + } + @Override + public List getPdpsInGroup(long groupKey){ + logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup("+groupKey+") called"); + if(groupKey < 0){ + throw new IllegalArgumentException("groupId must not be < 0"); + } + synchronized(emLock){ + checkBeforeOperationRun(true); + Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group"); + pdpsQuery.setParameter("group", getGroup(groupKey)); + return pdpsQuery.getResultList(); + } + } + @Override + public PdpEntity getPdp(long pdpKey){ + logger.debug("getPdp(int pdpKey) as getPdp("+pdpKey+") called"); + if(pdpKey < 0){ + throw new IllegalArgumentException("pdpKey must be at least 0"); + } + synchronized(emLock){ + checkBeforeOperationRun(true); + //check if group exists + Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey"); + pdpQuery.setParameter("pdpKey", pdpKey); + List pdpQueryList; + try{ + pdpQueryList = pdpQuery.getResultList(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get pdp with pdpQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get pdp with pdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get pdp "+pdpKey); + } + if(pdpQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Pdp does not exist with pdpKey "+pdpKey); + PolicyLogger.error("Pdp does not exist with pdpKey "+pdpKey); + throw new PersistenceException("Pdp does not exist with pdpKey "+pdpKey); + } else if(pdpQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database"); + PolicyLogger.error("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database"); + throw new PersistenceException("Somehow, more than one pdp with the pdpKey "+pdpKey+" were found in the database"); + } + return (PdpEntity)pdpQueryList.get(0); + } + } + + //FIXME: maybe this should be boolean + public void deletePolicy(String policyToDeletes){ + synchronized(emLock){ +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + checkBeforeOperationRun(); + logger.debug("deletePolicy(String policyToDeletes) as deletePolicy("+policyToDeletes+") called"); + String[] scopeNameAndType = getScopeAndNameAndType(policyToDeletes); + if(scopeNameAndType == null){ + throw new IllegalArgumentException("Could not parse file path"); + } + String realScope = scopeNameAndType[0]; + String realName = scopeNameAndType[1]; +// if(isTransactionOpen()){ +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + Query deletePolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName AND p.deleted=:deleted"); + deletePolicyQuery.setParameter("scope",realScope); + deletePolicyQuery.setParameter("policyName", realName); + deletePolicyQuery.setParameter("deleted", false); + List deletePolicyQueryList = deletePolicyQuery.getResultList(); + if(deletePolicyQueryList.size() < 1){ + logger.warn("The policy being deleted could not be found."); + return; + } else if(deletePolicyQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one policy with the same scope, name, and deleted status were found in the database"); + } else { + //em.getTransaction().begin(); + PolicyEntity policyToDelete = (PolicyEntity)deletePolicyQueryList.get(0); + policyToDelete.setDeleted(true); + if(policyToDelete.getConfigurationData() != null){ + ConfigurationDataEntity cde = em.find(ConfigurationDataEntity.class,policyToDelete.getConfigurationData().getConfigurationDataId()); + if(cde != null){ + cde.setDeleted(true); + } + } + if(policyToDelete.getActionBodyEntity() != null){ + ActionBodyEntity abe = em.find(ActionBodyEntity.class,policyToDelete.getActionBodyEntity().getActionBodyId()); + if(abe != null){ + abe.setDeleted(true); + } + } + + em.flush(); + this.policyId = policyToDelete.getPolicyId(); + + } + } + + } + + + @Override + public boolean isTransactionOpen() { + logger.debug("isTransactionOpen() as isTransactionOpen() called"); + synchronized(emLock){ + return em.isOpen() && em.getTransaction().isActive(); + } + } + + + @Override + public void clonePolicy(String oldPolicyPath, String newPolicyPath, String username){ + String[] oldPolicyData = getScopeAndNameAndType(oldPolicyPath); + String[] newPolicyData = getScopeAndNameAndType(newPolicyPath); + if(oldPolicyData == null || newPolicyData == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: " + //+oldPolicyPath+", "+newPolicyPath); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW+"Could not parse one or more of the path names: " + +oldPolicyPath+", "+newPolicyPath); + throw new IllegalArgumentException("Could not parse the oldPolicyPath or newPolicyPath"); + } + PolicyEntity oldPolicy; + try{ + oldPolicy = getPolicy(oldPolicyData[1],oldPolicyData[0]); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Could not get policy record to clone: " + //+oldPolicyData[1],e); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "PolicyDBDao", "Could not get policy record to clone: " + +oldPolicyData[1]); + throw new PersistenceException("Could not get policy record to clone"); + } + ConfigurationDataEntity clonedConfig = null; + if(oldPolicy.getConfigurationData() != null){ + clonedConfig = new ConfigurationDataEntity(); + em.persist(clonedConfig); + clonedConfig.setConfigBody(oldPolicy.getConfigurationData().getConfigBody()); + clonedConfig.setConfigType(oldPolicy.getConfigurationData().getConfigType()); + clonedConfig.setCreatedBy(username); + clonedConfig.setConfigurationName(getConfigFile(newPolicyData[1], newPolicyData[0], oldPolicy.getConfigurationData().getConfigType())); + clonedConfig.setDescription(oldPolicy.getConfigurationData().getDescription()); + clonedConfig.setModifiedBy(username); + em.flush(); + } + ActionBodyEntity clonedAction = null; + if(oldPolicy.getActionBodyEntity() != null){ + clonedAction = new ActionBodyEntity(); + em.persist(clonedAction); + clonedAction.setActionBody(oldPolicy.getActionBodyEntity().getActionBody()); + clonedAction.setActionBodyName(newPolicyData[0]+"."+newPolicyData[1]+".json"); + clonedAction.setCreatedBy(username); + clonedAction.setModifiedBy(username); + em.flush(); + } + + + } + + @Override + public void createPolicy(String filePath, String username) { + logger.debug("createPolicy(String filePath, String username) as createPolicy("+filePath+","+username+") called"); + //get just the scope and file name + //its actually scope, name, and type now + String[] scopeAndName = getScopeAndNameAndType(filePath); + if(scopeAndName == null){ + throw new IllegalArgumentException("The file path could not be parsed"); + } + PolicyRestAdapter policy = new PolicyRestAdapter(); + + policy.setPolicyType(scopeAndName[2]); + policy.setPolicyDescription(""); + + String policyName = scopeAndName[1]; + try{ + policyName = stripPolicyName(policyName); + }catch(IllegalArgumentException e){ + if(scopeAndName[2].equals("Config")){ + //TODO:EELF Cleanup - Remove logger + //logger.error(e.getMessage()); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Exception calling stripPolicyName with policy name: "+policyName); + throw new IllegalArgumentException(e.getMessage(),e); + } else { + logger.warn(e.getMessage()); + } + } + policy.setPolicyName(policyName); + String policyDataString = null; + InputStream fileContentStream = null; + try { + fileContentStream = new FileInputStream(filePath); + policyDataString = IOUtils.toString(fileContentStream); + } catch (FileNotFoundException e) { + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught FileNotFoundException on new FileInputStream("+filePath+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught FileNotFoundException on new FileInputStream("+filePath+")"); + throw new IllegalArgumentException("The file path does not exist"); + } catch(IOException e2){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught IOException on newIOUtils.toString("+fileContentStream+")",e2); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, "PolicyDBDao", "Caught IOException on newIOUtils.toString("+fileContentStream+")"); + throw new IllegalArgumentException("The file path cannot be read"); + } finally { + IOUtils.closeQuietly(fileContentStream); + } + if(policyDataString == null){ + throw new IllegalArgumentException("The file path cannot be read"); + } + try{ + String policyDescription = getElementFromXMLString("/Description", policyDataString); + if(policyDescription != null){ + policy.setPolicyDescription(policyDescription); + } + } catch(Exception e){ + logger.warn("Could not get description from the policy file"); + } + if(scopeAndName[2].equals("Config")){ + //this method is not used for config, since there is no way to get config info (could be modified to) + String configPath; + try{ + configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString); + if(configPath == null){ + throw new NullPointerException("configPath is null"); + } + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not get config file path from policy file",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get config file path from policy file"); + throw new IllegalArgumentException("Could not get config file path from policy file"); + } + configPath = processConfigPath(configPath); + logger.debug("The location of our config file is: "+configPath); + policy.setConfigType(getPolicySubType(configPath)); + logger.debug("Config type is: "+policy.getConfigType()); + + String configDataString = readConfigFile(configPath); + policy.setConfigBodyData(configDataString); + } + createPolicy(policy,username,scopeAndName[0],scopeAndName[1],policyDataString); + } + private String processConfigPath(String configPath){ + String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS); + if(webappsPath == null){ + logger.error("Webapps property does not exist"); + throw new IllegalArgumentException("Webapps property does not exist"); + } + configPath = configPath.replace("$URL", webappsPath); + //make sure the correct slashes are in + try{ + configPath = Paths.get(configPath).toString(); + } catch(InvalidPathException e){ + logger.error("Invalid config path: "+configPath); + throw new IllegalArgumentException("Invalid config path: "+configPath); + } + return configPath; + } + private String readConfigFile(String configPath){ + String configDataString = null; + InputStream configContentStream = null; + try { + configContentStream = new FileInputStream(configPath); + configDataString = IOUtils.toString(configContentStream); + } catch (FileNotFoundException e) { + logger.error("Caught FileNotFoundException on new FileInputStream("+configPath+")",e); + throw new IllegalArgumentException("The config file path does not exist"); + } catch(IOException e2){ + logger.error("Caught IOException on newIOUtils.toString("+configContentStream+")",e2); + throw new IllegalArgumentException("The config file path cannot be read"); + } finally { + IOUtils.closeQuietly(configContentStream); + } + if(configDataString == null){ + throw new IllegalArgumentException("The config file path cannot be read"); + } + return configDataString; + } + + @Override + public void createPolicy(Policy policy, String username){ + logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy("+policy+","+username+") called"); + String policyScope = computeScope(policy.policyAdapter.getParentPath(),policy.policyAdapter.getUserGitPath()); + + //Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP + //and this transaction is intercepted up stream. + InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType)policy.getCorrectPolicyDataObject()); + String policyDataString; + try { + policyDataString = IOUtils.toString(policyXmlStream); + } catch (IOException e) { + policyDataString = "could not read"; + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught IOException on IOUtils.toString("+policyXmlStream+")",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught IOException on IOUtils.toString("+policyXmlStream+")"); + throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter."); + } + IOUtils.closeQuietly(policyXmlStream); + String configPath = ""; + if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) { + configPath = evaluateXPath("/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", policyDataString); + } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) { + configPath = evaluateXPath("/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " +policy.policyAdapter.getActionAttribute()+ ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", policyDataString); + } + + String prefix = null; + if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Config")) { + + prefix = configPath.substring(configPath.indexOf(policyScope+".")+policyScope.concat(".").length(), configPath.indexOf(policy.policyAdapter.getPolicyName())); + if(isNullOrEmpty(policy.policyAdapter.getConfigBodyData())){ + String configData = ""; + try{ + String newConfigPath = configPath; + try{ + newConfigPath = processConfigPath(newConfigPath); + }catch(Exception e2){ + logger.error("Could not process config path: "+newConfigPath,e2); + } + configData = readConfigFile(newConfigPath); + }catch(Exception e){ + logger.error("Could not read config body data for "+configPath,e); + } + policy.policyAdapter.setConfigBodyData(configData); + } + + } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")) { + + prefix = "Action_"; + + } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Decision")) { + + prefix = "Decision_"; + } + + if(!(policy.policyAdapter.getData() instanceof PolicyType)){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The data field is not an instance of PolicyType"); + PolicyLogger.error("The data field is not an instance of PolicyType"); + throw new IllegalArgumentException("The data field is not an instance of PolicyType"); + } + String finalName = prefix+policy.policyAdapter.getPolicyName()+"."+((PolicyType)policy.policyAdapter.getData()).getVersion()+".xml"; + if(policy.policyAdapter.getConfigType() == null || policy.policyAdapter.getConfigType().equals("")){ + //we need to make it + //get the config file extension + String ext = ""; + if (configPath != null) { + if (!configPath.equalsIgnoreCase("")) { + ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());; + } + } + + if(ext.contains("txt")){ + policy.policyAdapter.setConfigType(OTHER_CONFIG); + } else if(ext.contains("json")){ + policy.policyAdapter.setConfigType(JSON_CONFIG); + } else if(ext.contains("xml")){ + policy.policyAdapter.setConfigType(XML_CONFIG); + } else if(ext.contains("properties")){ + policy.policyAdapter.setConfigType(PROPERTIES_CONFIG); + } else { + if (policy.policyAdapter.getPolicyType().equalsIgnoreCase("Action")){ + policy.policyAdapter.setConfigType(JSON_CONFIG); + } + } + } + createPolicy(policy.policyAdapter, username, policyScope,finalName,policyDataString); + + } + + @Override + public void close(){ + synchronized(emLock){ + if(em.isOpen()){ + if(em.getTransaction().isActive()){ + em.getTransaction().rollback(); + } + em.close(); + } + if(transactionTimer instanceof Thread){ + transactionTimer.interrupt(); + } + } + } + + + + @Override + public void createGroup(String groupId, String groupName, String groupDescription, String username) { + logger.debug("deletePolicy(String policyToDeletes) as createGroup("+groupId+", "+groupName+", "+groupDescription+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + //parameter check + if(isNullOrEmpty(groupId, groupName, username)){ + throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty"); + } + if(!(groupDescription instanceof String)){ + groupDescription = ""; + } + + synchronized(emLock){ + checkBeforeOperationRun(); + Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + checkGroupQuery.setParameter("groupId", groupId); + checkGroupQuery.setParameter("deleted", false); + List checkGroupQueryList; + try{ + checkGroupQueryList = checkGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on checkGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check for existing group"); + } + if(checkGroupQueryList.size() > 0){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group being added already exists with id "+groupId); + PolicyLogger.error("The group being added already exists with id "+groupId); + throw new PersistenceException("The group being added already exists with id "+groupId); + } + //em.getTransaction().begin(); + GroupEntity newGroup = new GroupEntity(); + em.persist(newGroup); + newGroup.setCreatedBy(username); + newGroup.setModifiedBy(username); + newGroup.setGroupName(groupName); + newGroup.setGroupId(groupId); + newGroup.setDescription(groupDescription); + + em.flush(); + this.groupId = newGroup.getGroupKey(); + } + } + + @Override + public void updateGroup(EcompPDPGroup group, String username){ + logger.debug("updateGroup(PDPGroup group) as updateGroup("+group+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + + //parameter check + if(group == null){ + throw new IllegalArgumentException("PDPGroup group must not be null"); + } + if(isNullOrEmpty(group.getId(), username)){ + throw new IllegalArgumentException("group.getId() and username must not be null or empty"); + } + + synchronized(emLock){ + checkBeforeOperationRun(); + Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + getGroupQuery.setParameter("groupId", group.getId()); + getGroupQuery.setParameter("deleted", false); + List getGroupQueryList; + try{ + getGroupQueryList = getGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on getGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get group "+group.getId()+" for editing"); + } + if(getGroupQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group cannot be found to update with id "+group.getId()); + PolicyLogger.error("The group cannot be found to update with id "+group.getId()); + throw new PersistenceException("The group cannot be found to update with id "+group.getId()); + } else if(getGroupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + } + //em.getTransaction().begin(); + GroupEntity groupToUpdate = (GroupEntity)getGroupQueryList.get(0); + if(!stringEquals(groupToUpdate.getModifiedBy(), username)){ + groupToUpdate.setModifiedBy(username); + } + if(group.getDescription() != null && !stringEquals(group.getDescription(),groupToUpdate.getDescription())){ + groupToUpdate.setDescription(group.getDescription()); + } + //let's find out what policies have been deleted + StdPDPGroup oldGroup = null; + try { + oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId()); + } catch (PAPException e1) { + //TODO:EELF Cleanup - Remove logger + //logger.error("We cannot get the group from the papEngine to delete policies",e1); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, "PolicyDBDao", "We cannot get the group from the papEngine to delete policies"); + } + if(oldGroup == null){ + //TODO:EELF Cleanup - Remove logger + //logger.error("We cannot get the group from the papEngine to delete policies"); + PolicyLogger.error("We cannot get the group from the papEngine to delete policies"); + } else { + + Set newPolicySet = new HashSet(group.getPolicies().size()); + //a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison + for(PDPPolicy pol: group.getPolicies()){ + newPolicySet.add(pol.getId()); + } + for(PDPPolicy pol : oldGroup.getPolicies()){ + //should be fast since getPolicies uses a HashSet in StdPDPGroup + if(!newPolicySet.contains(pol.getId())){ + String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId()); + PolicyEntity policyToDelete; + try{ + policyToDelete = getPolicy(scopeAndName[0],scopeAndName[1]); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Could not get policy to remove: "+pol.getId(),e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Could not get policy to remove: "+pol.getId()); + throw new PersistenceException("Could not get policy to remove: "+pol.getId()); + } + groupToUpdate.getPolicies().remove(policyToDelete); + + } + } + } + if(group.getName() != null && !stringEquals(group.getName(),groupToUpdate.getgroupName())){ + //we need to check if the new id exists in the database + String newGroupId = createNewPDPGroupId(group.getName()); + Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + checkGroupQuery.setParameter("groupId", newGroupId); + checkGroupQuery.setParameter("deleted", false); + List checkGroupQueryList; + try{ + checkGroupQueryList = checkGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on checkGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on checkGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check for existing group"); + } + if(checkGroupQueryList.size() != 0){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The new group name already exists, group id "+newGroupId); + PolicyLogger.error("The new group name already exists, group id "+newGroupId); + throw new PersistenceException("The new group name already exists, group id "+newGroupId); + } + groupToUpdate.setGroupId(newGroupId); + groupToUpdate.setGroupName(group.getName()); + this.newGroupId = group.getId(); + } + + em.flush(); + this.groupId = groupToUpdate.getGroupKey(); + } + } + + @Override + public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) { + logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup("+pdpID+", "+groupID+", "+pdpName+", "+pdpDescription+", "+pdpJmxPort+", "+username+") called"); + if(isNullOrEmpty(pdpID, groupID,pdpName,username)){ + throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty"); + } + if(!(pdpDescription instanceof String)){ + pdpDescription = ""; + } +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + + synchronized(emLock){ + checkBeforeOperationRun(); + Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + checkGroupQuery.setParameter("groupId", groupID); + checkGroupQuery.setParameter("deleted", false); + List checkGroupQueryList; + try{ + checkGroupQueryList = checkGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check for existing group on checkGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check for existing group"); + } + if(checkGroupQueryList.size() != 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group does not exist"); + PolicyLogger.error("The group does not exist"); + throw new PersistenceException("The group does not exist"); + } + Query checkDuplicateQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted"); + checkDuplicateQuery.setParameter("pdpId", pdpID); + checkDuplicateQuery.setParameter("deleted", false); + List checkDuplicateList; + try{ + checkDuplicateList = checkDuplicateQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check for duplicate PDP "+pdpID+" on checkDuplicateQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check for duplicate PDP "+pdpID); + } + PdpEntity newPdp; + if(checkDuplicateList.size() > 0){ + logger.warn("PDP already exists with id "+pdpID); + newPdp = (PdpEntity)checkDuplicateList.get(0); + } else { + newPdp = new PdpEntity(); + em.persist(newPdp); + } + + newPdp.setCreatedBy(username); + newPdp.setDeleted(false); + newPdp.setDescription(pdpDescription); + newPdp.setGroup((GroupEntity)checkGroupQueryList.get(0)); + newPdp.setJmxPort(pdpJmxPort); + newPdp.setModifiedBy(username); + newPdp.setPdpId(pdpID); + newPdp.setPdpName(pdpName); + + em.flush(); + this.pdpId = newPdp.getPdpKey(); + + } + } + + + @Override + public void updatePdp(EcompPDP pdp, String username){ + logger.debug("updatePdp(PDP pdp, String username) as updatePdp("+pdp+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + //parameter check + if(pdp == null){ + throw new IllegalArgumentException("PDP pdp must not be null"); + } + if(isNullOrEmpty(pdp.getId(),username)){ + throw new IllegalArgumentException("pdp.getId() and username must not be null or empty"); + } + + synchronized(emLock){ + checkBeforeOperationRun(); + Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted"); + getPdpQuery.setParameter("pdpId", pdp.getId()); + getPdpQuery.setParameter("deleted", false); + List getPdpQueryList; + try{ + getPdpQueryList = getPdpQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on getPdpQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get PDP "+pdp.getId()); + } + if(getPdpQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The pdp cannot be found to update with id "+pdp.getId()); + PolicyLogger.error("The pdp cannot be found to update with id "+pdp.getId()); + throw new PersistenceException("The pdp cannot be found to update with id "+pdp.getId()); + } else if(getPdpQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + } + //em.getTransaction().begin(); + PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0); + if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){ + pdpToUpdate.setModifiedBy(username); + } + if(pdp.getDescription() != null && !stringEquals(pdp.getDescription(),pdpToUpdate.getDescription())){ + pdpToUpdate.setDescription(pdp.getDescription()); + } + if(pdp.getName() != null && !stringEquals(pdp.getName(),pdpToUpdate.getPdpName())){ + pdpToUpdate.setPdpName(pdp.getName()); + } + if(pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())){ + pdpToUpdate.setJmxPort(pdp.getJmxPort()); + } + + em.flush(); + this.pdpId = pdpToUpdate.getPdpKey(); + } + } + + @Override + public void movePdp(EcompPDP pdp, EcompPDPGroup group, String username){ + logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp("+pdp+","+group+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + if(pdp == null || group == null){ + throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null"); + } + if(isNullOrEmpty(username,pdp.getId(),group.getId())){ + throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty"); + } + + synchronized(emLock){ + checkBeforeOperationRun(); + //check if pdp exists + Query getPdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted"); + getPdpQuery.setParameter("pdpId", pdp.getId()); + getPdpQuery.setParameter("deleted", false); + List getPdpQueryList; + try{ + getPdpQueryList = getPdpQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on getPdpQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getPdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get pdp to move with id "+pdp.getId()); + } + if(getPdpQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The pdp cannot be found to move with id "+pdp.getId()); + PolicyLogger.error("The pdp cannot be found to move with id "+pdp.getId()); + throw new PersistenceException("The pdp cannot be found to move with id "+pdp.getId()); + } else if(getPdpQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one pdp with the same id "+pdp.getId()+" and deleted status were found in the database"); + } + + //check if new group exists + Query checkGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + checkGroupQuery.setParameter("groupId", group.getId()); + checkGroupQuery.setParameter("deleted", false); + List checkGroupQueryList; + try{ + checkGroupQueryList = checkGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get group on checkGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get group on checkGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get new group "+group.getId()); + } + if(checkGroupQueryList.size() != 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group "+group.getId()+" does not exist"); + PolicyLogger.error("The group "+group.getId()+" does not exist"); + throw new PersistenceException("The group "+group.getId()+" does not exist"); + } + GroupEntity groupToMoveInto = (GroupEntity)checkGroupQueryList.get(0); + //move it + //em.getTransaction().begin(); + PdpEntity pdpToUpdate = (PdpEntity)getPdpQueryList.get(0); + pdpToUpdate.setGroup(groupToMoveInto); + if(!stringEquals(pdpToUpdate.getModifiedBy(), username)){ + pdpToUpdate.setModifiedBy(username); + } + + em.flush(); + this.pdpId = pdpToUpdate.getPdpKey(); + } + } + + @Override + public void changeDefaultGroup(EcompPDPGroup group, String username){ + logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup("+group+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + //parameter check + if(group == null){ + throw new IllegalArgumentException("PDPGroup group must not be null"); + } + if(isNullOrEmpty(group.getId(),username)){ + throw new IllegalArgumentException("group.getId() and username must not be null or empty"); + } + + synchronized(emLock){ + checkBeforeOperationRun(); + Query getGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + getGroupQuery.setParameter("groupId", group.getId()); + getGroupQuery.setParameter("deleted", false); + List getGroupQueryList; + try{ + getGroupQueryList = getGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on getGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on getGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get group "+group.getId()); + } + if(getGroupQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group cannot be found to set default with id "+group.getId()); + PolicyLogger.error("The group cannot be found to set default with id "+group.getId()); + throw new PersistenceException("The group cannot be found to set default with id "+group.getId()); + } else if(getGroupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + PolicyLogger.error("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one group with the same id "+group.getId()+" and deleted status were found in the database"); + } + //em.getTransaction().begin(); + GroupEntity newDefaultGroup = (GroupEntity)getGroupQueryList.get(0); + newDefaultGroup.setDefaultGroup(true); + if(!stringEquals(newDefaultGroup.getModifiedBy(), username)){ + newDefaultGroup.setModifiedBy(username); + } + + em.flush(); + this.groupId = newDefaultGroup.getGroupKey(); + Query setAllGroupsNotDefault = em.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g.groupKey<>:groupKey"); + //not going to set modified by for all groups + setAllGroupsNotDefault.setParameter("defaultGroup", false); + setAllGroupsNotDefault.setParameter("deleted", false); + setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey()); + try{ + logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default"); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception on setAllGroupsNotDefault.executeUpdate()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception on setAllGroupsNotDefault.executeUpdate()"); + throw new PersistenceException("Could not set all other groups default to false"); + } + + em.flush(); + } + } + + + @Override + public void deleteGroup(EcompPDPGroup group, EcompPDPGroup moveToGroup, String username) throws PAPException { + logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup("+group+", "+moveToGroup+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + if(group == null){ + throw new IllegalArgumentException("PDPGroup group cannot be null"); + } + if(isNullOrEmpty(username,group.getId())){ + throw new IllegalArgumentException("group.getId() and and username must not be null or empty"); + } + + if(group.isDefaultGroup()){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be."); + PolicyLogger.error("The default group "+group.getId()+" was attempted to be deleted. It cannot be."); + throw new PAPException("You cannot delete the default group."); + } + synchronized(emLock){ + checkBeforeOperationRun(); + Query deleteGroupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + deleteGroupQuery.setParameter("groupId", group.getId()); + deleteGroupQuery.setParameter("deleted", false); + List deleteGroupQueryList; + try{ + deleteGroupQueryList = deleteGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check if group exists deleteGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group exists"); + } + if(deleteGroupQueryList.size() < 1){ + logger.warn("The group could not be found with id " + group.getId()); + return; + } else if(deleteGroupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted"); + PolicyLogger.error("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted"); + throw new PersistenceException("Somehow, more than one group with the id "+group.getId()+" were found in the database that are not deleted"); + } + + Query pdpsInGroupQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted"); + pdpsInGroupQuery.setParameter("group", ((GroupEntity)deleteGroupQueryList.get(0))); + pdpsInGroupQuery.setParameter("deleted", false); + List pdpsInGroupList; + try{ + pdpsInGroupList = pdpsInGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get PDPs in group"); + } + //em.getTransaction().begin(); + if(pdpsInGroupList.size() > 0){ + if(moveToGroup != null){ + Query checkMoveToGroupQuery = em.createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted"); + checkMoveToGroupQuery.setParameter("groupId", moveToGroup.getId()); + checkMoveToGroupQuery.setParameter("deleted", false); + List checkMoveToGroupList; + try{ + checkMoveToGroupList = checkMoveToGroupQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group exists"); + } + if(checkMoveToGroupList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("The group could not be found with id " + moveToGroup.getId()); + PolicyLogger.error("The group could not be found with id " + moveToGroup.getId()); + throw new PersistenceException("The group could not be found with id " + moveToGroup.getId()); + } else if(checkMoveToGroupList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted"); + PolicyLogger.error("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted"); + throw new PersistenceException("Somehow, more than one group with the id "+moveToGroup.getId()+" were found in the database that are not deleted"); + } else { + GroupEntity newGroup = (GroupEntity)checkMoveToGroupList.get(0); + for(Object pdpObject : pdpsInGroupList){ + PdpEntity pdp = (PdpEntity)pdpObject; + pdp.setGroup(newGroup); + if(!stringEquals(pdp.getModifiedBy(),username)){ + pdp.setModifiedBy(username); + } + try{ + + em.flush(); + this.newGroupId = newGroup.getGroupId(); + } catch(PersistenceException e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught PersistenceException trying to set pdp group to null on em.flush()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught PersistenceException trying to set pdp group to null on em.flush()"); + throw new PersistenceException("Query failed trying to set pdp group to "); + } + } + } + } else { + //TODO:EELF Cleanup - Remove logger + //logger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to"); + PolicyLogger.error("Group "+group.getId()+" is trying to be delted with PDPs. No group was provided to move them to"); + throw new PAPException("Group has PDPs. Must provide a group for them to move to"); + } + } + + //delete group here + + GroupEntity groupToDelete = (GroupEntity)deleteGroupQueryList.get(0); + groupToDelete.setDeleted(true); + if(!stringEquals(groupToDelete.getModifiedBy(), username)){ + groupToDelete.setModifiedBy(username); + } + + //try{ + + em.flush(); + this.groupId = groupToDelete.getGroupKey(); + //return; + //} catch(PersistenceException pe){ + //logger.error("Database error while marking policy or config as deleted"); + //throw new PersistenceException("Database error while marking policy or config as deleted"); + //} + } + } + + @Override + public void addPolicyToGroup(String groupID, String policyID, String username) { + logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + if(isNullOrEmpty(groupID, policyID, username)){ + throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty"); + } + synchronized(emLock){ + checkBeforeOperationRun(); + //check if group exists + Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + groupQuery.setParameter("groupId", groupID); + groupQuery.setParameter("deleted", false); + List groupQueryList; + try{ + groupQueryList = groupQuery.getResultList(); + }catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check if group exists groupQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group "+groupID+" exists"); + } + if(groupQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Group policy is being added to does not exist with id "+groupID); + PolicyLogger.error("Group policy is being added to does not exist with id "+groupID); + throw new PersistenceException("Group policy is being added to does not exist with id "+groupID); + } else if(groupQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); + PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); + throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); + } + //we need to convert the form of the policy id that is used groups into the form that is used + //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml) + String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID); + Query policyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p.deleted=:deleted"); + policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]); + policyQuery.setParameter("scope", policyNameScopeAndVersion[1]); + policyQuery.setParameter("deleted", false); + List policyQueryList; + try{ + policyQueryList = policyQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check if policy exists policyQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if policy exists policyQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if policy "+policyNameScopeAndVersion[0]+" exists"); + } + if(policyQueryList.size() < 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]); + PolicyLogger.error("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]); + throw new PersistenceException("Policy being added to the group does not exist with policy id "+policyNameScopeAndVersion[0]); + } else if(policyQueryList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); + PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); + throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); + } + //em.getTransaction().begin(); + GroupEntity group = (GroupEntity)groupQueryList.get(0); + PolicyEntity policy = (PolicyEntity)policyQueryList.get(0); + group.addPolicyToGroup(policy); + em.flush(); + } + } + + //this means delete pdp not just remove from group + @Override + public void removePdpFromGroup(String pdpID, String username) { + logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup("+pdpID+","+username+") called"); +// if(isTransactionOpen()){ +// logger.error("A transaction is already open which has not been committed"); +// throw new IllegalStateException("A transaction is already open which has not been committed"); +// } + if(isNullOrEmpty(pdpID,username)){ + throw new IllegalArgumentException("pdpID and username must not be null or empty"); + } + synchronized(emLock){ + checkBeforeOperationRun(); + Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted"); + pdpQuery.setParameter("pdpId", pdpID); + pdpQuery.setParameter("deleted", false); + List pdpList; + try{ + pdpList = pdpQuery.getResultList(); + } catch(Exception e){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Caught Exception trying to check if pdp exists pdpQuery.getResultList()",e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if pdp exists pdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if pdp "+pdpID+" exists"); + } + if(pdpList.size() > 1){ + //TODO:EELF Cleanup - Remove logger + //logger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted"); + PolicyLogger.error("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted"); + throw new PersistenceException("Somehow, more than one pdp with the id "+pdpID+" were found in the database that are not deleted"); + } else if(pdpList.size() < 1){ + //logger.warn("Pdp being removed does not exist with id "+pdpID); + PolicyLogger.error("Pdp being removed does not exist with id "+pdpID); + return; + } + //em.getTransaction().begin(); + PdpEntity pdp = (PdpEntity)pdpList.get(0); + pdp.setGroup(null); + if(!stringEquals(pdp.getModifiedBy(),username)){ + pdp.setModifiedBy(username); + } + pdp.setDeleted(true); + + em.flush(); + this.pdpId = pdp.getPdpKey(); + } + } + } + + + + private static String getDefaultWorkspace(){ + return "admin"; + } + + private PolicyDBDao(){ + + } + public static PolicyDBDaoTestClass getPolicyDBDaoTestClass(){ + return new PolicyDBDao().new PolicyDBDaoTestClass(); + } + final class PolicyDBDaoTestClass { + String[] getScopeAndNameAndType(final String path){ + return PolicyDBDao.getScopeAndNameAndType(path); + } + String getGitPath(){ + return PolicyDBDao.getGitPath(); + } + String getConfigFile(String filename, String scope, PolicyRestAdapter policy){ + return PolicyDBDao.this.getConfigFile(filename, scope, policy); + } + String computeScope(String fullPath, String pathToExclude){ + return PolicyDBDao.computeScope(fullPath, pathToExclude); + } + String encryptPassword(String password) throws Exception{ + return PolicyDBDao.encryptPassword(password); + } + String decryptPassword(String password) throws Exception{ + return PolicyDBDao.decryptPassword(password); + } + String getDescriptionFromXacml(String xacmlData){ + return PolicyDBDao.getDescriptionFromXacml(xacmlData); + } + + } + +} -- cgit 1.2.3-korg