X-Git-Url: https://gerrit.onap.org/r/gitweb?p=policy%2Fengine.git;a=blobdiff_plain;f=ONAP-PAP-REST%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Fpap%2Fxacml%2Frest%2FXACMLPapServlet.java;h=e8df2bbdfb689bd40e7f0d1b4fe54170d6405b84;hp=680c4d579a679b10c075dbefbca4d6d61552cf05;hb=2f41a033ed0eae09aa1624d8287687de8a972a5d;hpb=4c38ea083e71d3be81b57a2c865572837fb72379 diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java index 680c4d579..e8df2bbdf 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java @@ -2,7 +2,8 @@ * ============LICENSE_START======================================================= * ONAP-PAP-REST * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,36 +21,29 @@ package org.onap.policy.pap.xacml.rest; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.api.pap.PDPStatus; +import com.att.research.xacml.util.FactoryException; +import com.att.research.xacml.util.XACMLProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Splitter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.ConnectException; -import java.net.HttpURLConnection; import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLDecoder; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Properties; -import java.util.Scanner; import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; import javax.persistence.PersistenceException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; @@ -59,7 +53,6 @@ import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.apache.commons.io.IOUtils; import org.onap.policy.common.ia.IntegrityAudit; import org.onap.policy.common.im.AdministrativeStateException; @@ -68,22 +61,23 @@ import org.onap.policy.common.im.IntegrityMonitor; import org.onap.policy.common.im.IntegrityMonitorException; import org.onap.policy.common.im.IntegrityMonitorProperties; import org.onap.policy.common.im.StandbyStatusException; -import org.onap.policy.common.logging.ONAPLoggingContext; -import org.onap.policy.common.logging.ONAPLoggingUtils; +import org.onap.policy.common.logging.OnapLoggingContext; +import org.onap.policy.common.logging.OnapLoggingUtils; import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; import org.onap.policy.common.logging.flexlogger.FlexLogger; import org.onap.policy.common.logging.flexlogger.Logger; -import org.onap.policy.pap.xacml.rest.components.PolicyDBDao; -import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction; +import org.onap.policy.pap.xacml.rest.components.HandleIncomingNotifications; +import org.onap.policy.pap.xacml.rest.components.PolicyDbDao; +import org.onap.policy.pap.xacml.rest.components.PolicyDbDaoTransaction; import org.onap.policy.pap.xacml.rest.handler.APIRequestHandler; import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler; import org.onap.policy.pap.xacml.rest.handler.SavePolicyHandler; import org.onap.policy.pap.xacml.restAuth.CheckPDP; -import org.onap.policy.rest.XACMLRest; -import org.onap.policy.rest.XACMLRestProperties; -import org.onap.policy.rest.dao.PolicyDBException; -import org.onap.policy.utils.CryptoUtils; +import org.onap.policy.rest.XacmlRest; +import org.onap.policy.rest.XacmlRestProperties; +import org.onap.policy.rest.dao.PolicyDbException; +import org.onap.policy.utils.PeCryptoUtils; import org.onap.policy.utils.PolicyUtils; import org.onap.policy.xacml.api.XACMLErrorConstants; import org.onap.policy.xacml.api.pap.ONAPPapEngineFactory; @@ -96,31 +90,23 @@ import org.onap.policy.xacml.std.pap.StdPDPItemSetChangeNotifier.StdItemSetChang import org.onap.policy.xacml.std.pap.StdPDPPolicy; import org.onap.policy.xacml.std.pap.StdPDPStatus; -import com.att.research.xacml.api.pap.PAPException; -import com.att.research.xacml.api.pap.PDPPolicy; -import com.att.research.xacml.api.pap.PDPStatus; -import com.att.research.xacml.util.FactoryException; -import com.att.research.xacml.util.XACMLProperties; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Splitter; - /** - * Servlet implementation class XacmlPapServlet + * Servlet implementation class XacmlPapServlet. */ @WebServlet( - description = "Implements the XACML PAP RESTful API.", - urlPatterns = {"/"}, - loadOnStartup = 1, - initParams = { - @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.pap.properties", - description = "The location of the properties file holding configuration information.") - }) + description = "Implements the XACML PAP RESTful API.", + urlPatterns = {"/"}, + loadOnStartup = 1, + initParams = {@WebInitParam( + name = "XACML_PROPERTIES_NAME", + value = "xacml.pap.properties", + description = "The location of the properties file holding configuration information.")}) public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeListener, Runnable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = FlexLogger.getLogger(XACMLPapServlet.class); // audit (transaction) LOGGER private static final Logger auditLogger = FlexLogger.getLogger("auditLogger"); - //Persistence Unit for JPA + // Persistence Unit for JPA private static final String PERSISTENCE_UNIT = "XACML-PAP-REST"; private static final String AUDIT_PAP_PERSISTENCE_UNIT = "auditPapPU"; // Client Headers. @@ -131,27 +117,24 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList private static final String REGEX = "[0-9a-zA-Z._ ]*"; /* - * List of Admin Console URLs. - * Used to send notifications when configuration changes. + * List of Admin Console URLs. Used to send notifications when configuration changes. * - * The CopyOnWriteArrayList *should* protect from concurrency errors. - * This list is seldom changed but often read, so the costs of this approach make sense. + * The CopyOnWriteArrayList *should* protect from concurrency errors. This list is seldom + * changed but often read, so the costs of this approach make sense. */ private static final CopyOnWriteArrayList adminConsoleURLStringList = new CopyOnWriteArrayList<>(); private static String configHome; private static String actionHome; /* - * This PAP instance's own URL. - * Need this when creating URLs to send to the PDPs so they can GET the Policy files from this process. + * This PAP instance's own URL. Need this when creating URLs to send to the PDPs so they can GET + * the Policy files from this process. */ - private static String papURL = null; + private static String papUrl = null; // The heartbeat thread. private static Heartbeat heartbeat = null; private static Thread heartbeatThread = null; - //The entity manager factory for JPA access - private static EntityManagerFactory emf; - private static PolicyDBDao policyDBDao; + private static PolicyDbDao policyDbDao; /* * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes. */ @@ -163,7 +146,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList private static String papDbDriver = null; private static String papDbUrl = null; private static String papDbUser = null; - private static String papDbPassword = null; + private static String papDbPd = null; private static String papResourceName = null; private static String[] papDependencyGroupsFlatArray = null; private static String environment = null; @@ -172,7 +155,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList private transient IntegrityMonitor im; private transient IntegrityAudit ia; - //MicroService Model Properties + // MicroService Model Properties private static String msOnapName; private static String msPolicyName; /* @@ -180,7 +163,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList * this servlet starts. Its configurable by the admin. */ private static transient Thread initiateThread = null; - private transient ONAPLoggingContext baseLoggingContext = null; + private transient OnapLoggingContext baseLoggingContext = null; + private static final String GROUPID = "groupId"; /** * @see HttpServlet#HttpServlet() @@ -192,10 +176,11 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see Servlet#init(ServletConfig) */ + @Override public void init(ServletConfig config) throws ServletException { try { // Logging - baseLoggingContext = new ONAPLoggingContext(); + baseLoggingContext = new OnapLoggingContext(); // fixed data that will be the same in all logging output goes here try { String hostname = InetAddress.getLocalHost().getCanonicalHostName(); @@ -203,172 +188,165 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } catch (UnknownHostException e) { LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get hostname for logging", e); } + // Initialize - XACMLRest.xacmlInit(config); + XacmlRest.xacmlInit(config); // Load the properties - XACMLRest.loadXacmlProperties(null, null); + XacmlRest.loadXacmlProperties(null, null); /* * Retrieve the property values */ setCommonProperties(); - String papSiteName = XACMLProperties.getProperty(XACMLRestProperties.PAP_SITE_NAME); + String papSiteName = XACMLProperties.getProperty(XacmlRestProperties.PAP_SITE_NAME); if (papSiteName == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", - " ERROR: Bad papSiteName property entry"); + " ERROR: Bad papSiteName property entry"); throw new PAPException("papSiteName is null"); } - String papNodeType = XACMLProperties.getProperty(XACMLRestProperties.PAP_NODE_TYPE); + String papNodeType = XACMLProperties.getProperty(XacmlRestProperties.PAP_NODE_TYPE); if (papNodeType == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", - " ERROR: Bad papNodeType property entry"); + " ERROR: Bad papNodeType property entry"); throw new PAPException("papNodeType is null"); } - //Integer will throw an exception of anything is missing or unrecognized - int papTransWait = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)); + // Integer will throw an exception of anything is missing or + // unrecognized + int papTransWait = Integer.parseInt(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_TRANS_WAIT)); int papTransTimeout = - Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)); + Integer.parseInt(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_TRANS_TIMEOUT)); int papAuditTimeout = - Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); - //Boolean will default to false if anything is missing or unrecognized + Integer.parseInt(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_AUDIT_TIMEOUT)); + // Boolean will default to false if anything is missing or + // unrecognized boolean papAuditFlag = - Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG)); + Boolean.parseBoolean(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_RUN_AUDIT_FLAG)); boolean papFileSystemAudit = - Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_FLAG)); - String papDependencyGroups = XACMLProperties.getProperty(XACMLRestProperties.PAP_DEPENDENCY_GROUPS); + Boolean.parseBoolean(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_AUDIT_FLAG)); + String papDependencyGroups = XACMLProperties.getProperty(XacmlRestProperties.PAP_DEPENDENCY_GROUPS); if (papDependencyGroups == null) { throw new PAPException("papDependencyGroups is null"); } setPAPDependencyGroups(papDependencyGroups); - //Integer will throw an exception of anything is missing or unrecognized + // Integer will throw an exception of anything is missing or + // unrecognized int fpMonitorInterval = - Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL)); + Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FP_MONITOR_INTERVAL)); int failedCounterThreshold = - Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD)); + Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.FAILED_COUNTER_THRESHOLD)); int testTransInterval = - Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL)); + Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.TEST_TRANS_INTERVAL)); int writeFpcInterval = - Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL)); - LOGGER.debug("\n\n\n**************************************" - + "\n*************************************" - + "\n" - + "\n papDbDriver = " + papDbDriver - + "\n papDbUrl = " + papDbUrl - + "\n papDbUser = " + papDbUser - + "\n papTransWait = " + papTransWait - + "\n papTransTimeout = " + papTransTimeout - + "\n papAuditTimeout = " + papAuditTimeout - + "\n papAuditFlag = " + papAuditFlag - + "\n papFileSystemAudit = " + papFileSystemAudit - + "\n papResourceName = " + papResourceName - + "\n fpMonitorInterval = " + fpMonitorInterval - + "\n failedCounterThreshold = " + failedCounterThreshold - + "\n testTransInterval = " + testTransInterval - + "\n writeFpcInterval = " + writeFpcInterval - + "\n papSiteName = " + papSiteName - + "\n papNodeType = " + papNodeType - + "\n papDependencyGroupsList = " + papDependencyGroups - + "\n papIntegrityAuditPeriodSeconds = " + papIntegrityAuditPeriodSeconds - + "\n\n*************************************" - + "\n**************************************"); + Integer.parseInt(XACMLProperties.getProperty(IntegrityMonitorProperties.WRITE_FPC_INTERVAL)); + LOGGER.debug("\n\n\n**************************************" + "\n*************************************" + + "\n" + "\n papDbDriver = " + papDbDriver + "\n papDbUrl = " + papDbUrl + "\n papDbUser = " + + papDbUser + "\n papTransWait = " + papTransWait + "\n papTransTimeout = " + papTransTimeout + + "\n papAuditTimeout = " + papAuditTimeout + "\n papAuditFlag = " + papAuditFlag + + "\n papFileSystemAudit = " + papFileSystemAudit + "\n papResourceName = " + papResourceName + + "\n fpMonitorInterval = " + fpMonitorInterval + "\n failedCounterThreshold = " + + failedCounterThreshold + "\n testTransInterval = " + testTransInterval + "\n writeFpcInterval = " + + writeFpcInterval + "\n papSiteName = " + papSiteName + "\n papNodeType = " + papNodeType + + "\n papDependencyGroupsList = " + papDependencyGroups + "\n papIntegrityAuditPeriodSeconds = " + + papIntegrityAuditPeriodSeconds + "\n\n*************************************" + + "\n**************************************"); // Pull custom persistence settings Properties properties; try { properties = XACMLProperties.getProperties(); - LOGGER.debug("\n\n\n**************************************" - + "\n**************************************" - + "\n\n" - + "properties = " + properties - + "\n\n**************************************"); + LOGGER.debug("\n\n\n**************************************" + "\n**************************************" + + "\n\n" + "properties = " + properties + "\n\n**************************************"); } catch (IOException e) { - PolicyLogger - .error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " Error loading properties with: " - + "XACMLProperties.getProperties()"); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", + " Error loading properties with: " + "XACMLProperties.getProperties()"); throw new ServletException(e.getMessage(), e.getCause()); } // Create an IntegrityMonitor if (properties.getProperty(PERSISTENCE_JDBC_PWD) != null) { properties.setProperty(PERSISTENCE_JDBC_PWD, - CryptoUtils.decryptTxtNoExStr(properties.getProperty(PERSISTENCE_JDBC_PWD, ""))); + PeCryptoUtils.decrypt(properties.getProperty(PERSISTENCE_JDBC_PWD, ""))); } im = IntegrityMonitor.getInstance(papResourceName, properties); // Create an IntegrityAudit ia = new IntegrityAudit(papResourceName, AUDIT_PAP_PERSISTENCE_UNIT, properties); ia.startAuditThread(); - // Create the entity manager factory - setEMF(properties); // we are about to call the PDPs and give them their configuration. - // To do that we need to have the URL of this PAP so we can construct the Policy file URLs - setPAPURL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)); - //Create the policyDBDao - setPolicyDBDao(); + // To do that we need to have the URL of this PAP so we can + // construct the Policy file URLs + setPapUrl(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_URL)); + // Create the policyDBDao + setPolicyDbDao(); // Load our PAP engine, first create a factory ONAPPapEngineFactory factory = ONAPPapEngineFactory - .newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY)); + .newInstance(XACMLProperties.getProperty(XACMLProperties.PROP_PAP_PAPENGINEFACTORY)); // The factory knows how to go about creating a PAP Engine - setPAPEngine((PAPPolicyEngine) factory.newEngine()); - PolicyDBDaoTransaction addNewGroup = null; + setPAPEngine(factory.newEngine()); if (((org.onap.policy.xacml.std.pap.StdEngine) papEngine).wasDefaultGroupJustAdded) { - try { - addNewGroup = policyDBDao.getNewTransaction(); - OnapPDPGroup group = papEngine.getDefaultGroup(); - addNewGroup.createGroup(group.getId(), group.getName(), group.getDescription(), - "automaticallyAdded"); - addNewGroup.commitTransaction(); - addNewGroup = policyDBDao.getNewTransaction(); - addNewGroup.changeDefaultGroup(group, "automaticallyAdded"); - addNewGroup.commitTransaction(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", - " Error creating new default group in the database"); - if (addNewGroup != null) { - addNewGroup.rollbackTransaction(); - } - } + createDefaultGroupOnInit(); } - policyDBDao.setPapEngine((PAPPolicyEngine) XACMLPapServlet.papEngine); - if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG))) { + policyDbDao.setPapEngine(XACMLPapServlet.papEngine); + if (Boolean.parseBoolean(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_RUN_AUDIT_FLAG))) { /* * Auditing the local File System groups to be in sync with the Database */ - //get an AuditTransaction to lock out all other transactions - PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction(); + // get an AuditTransaction to lock out all other transactions + PolicyDbDaoTransaction auditTrans = policyDbDao.getNewAuditTransaction(); LOGGER.info("PapServlet: calling auditLocalFileSystem for PDP group audit"); LOGGER.info("PapServlet: old group is " + papEngine.getDefaultGroup().toString()); - //get the current filesystem group and update from the database if needed + // get the current filesystem group and update from the database + // if needed StdPDPGroup group = (StdPDPGroup) papEngine.getDefaultGroup(); - StdPDPGroup updatedGroup = policyDBDao.auditLocalFileSystem(group); + StdPDPGroup updatedGroup = policyDbDao.auditLocalFileSystem(group); if (updatedGroup != null) { papEngine.updateGroup(updatedGroup); } LOGGER.info("PapServlet: updated group is " + papEngine.getDefaultGroup().toString()); - //release the transaction lock + // sync up the config data from DB to file system + LOGGER.info("PapServlet: Sync config data from DB to file system"); + policyDbDao.synchronizeConfigDataInFileSystem(); + + // release the transaction lock auditTrans.close(); } - // Sanity check for URL. - if (XACMLPapServlet.papURL == null) { - throw new PAPException("The property " + XACMLRestProperties.PROP_PAP_URL + " is not valid: " + - XACMLPapServlet.papURL); - } - // Configurable - have the PAP servlet initiate sending the latest PDP policy/pip configuration + // Configurable - have the PAP servlet initiate sending the latest + // PDP policy/pip configuration // to all its known PDP nodes. - if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) { + if (Boolean.parseBoolean(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_INITIATE_PDP_CONFIG))) { startInitiateThreadService(new Thread(this)); } - // After startup, the PAP does Heartbeat's to each of the PDPs periodically - startHeartBeatService(new Heartbeat((PAPPolicyEngine) XACMLPapServlet.papEngine)); - + // After startup, the PAP does Heartbeat's to each of the PDPs + // periodically + startHeartBeatService(new Heartbeat(XACMLPapServlet.papEngine)); } catch (FactoryException | PAPException e) { PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " Failed to create engine"); throw new ServletException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; error: " + e); } catch (Exception e) { PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Failed to create engine - unexpected error"); + " Failed to create engine - unexpected error"); throw new ServletException( - XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; unexpected error: " + e); + XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP not initialized; unexpected error: " + e); + } + + } + + private void createDefaultGroupOnInit() { + PolicyDbDaoTransaction addNewGroup = null; + try { + addNewGroup = policyDbDao.getNewTransaction(); + OnapPDPGroup group = papEngine.getDefaultGroup(); + addNewGroup.createGroup(group.getId(), group.getName(), group.getDescription(), "automaticallyAdded"); + addNewGroup.commitTransaction(); + addNewGroup = policyDbDao.getNewTransaction(); + addNewGroup.changeDefaultGroup(group, "automaticallyAdded"); + addNewGroup.commitTransaction(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", + " Error creating new default group in the database"); + if (addNewGroup != null) { + addNewGroup.rollbackTransaction(); + } } } @@ -377,7 +355,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList initiateThread.start(); } - private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) { + @VisibleForTesting + protected static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) { try { mapper.writeValue(response.getOutputStream(), value); } catch (Exception e) { @@ -391,50 +370,49 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList XACMLPapServlet.heartbeatThread.start(); } - private static void setPolicyDBDao() throws ServletException { + private static void setPolicyDbDao() throws ServletException { try { - policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(getEmf()); + policyDbDao = PolicyDbDao.getPolicyDbDaoInstance(); } catch (Exception e) { throw new ServletException("Unable to Create Policy DBDao Instance", e); } } - private static void setEMF(Properties properties) throws ServletException { - emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, properties); - if (emf == null) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + - " Error creating entity manager factory with persistence unit: " - + PERSISTENCE_UNIT); - throw new ServletException("Unable to create Entity Manager Factory"); - } + public static PolicyDbDao getPolicyDbDao() { + return policyDbDao; + } + + private static void setPapUrl(String papUrl) { + XACMLPapServlet.papUrl = papUrl; } - private static void setPAPURL(String papURL) { - XACMLPapServlet.papURL = papURL; + public static String getPapUrl() { + return papUrl; } - private static void setPAPEngine(PAPPolicyEngine newEngine) { + @VisibleForTesting + protected static void setPAPEngine(PAPPolicyEngine newEngine) { XACMLPapServlet.papEngine = newEngine; } private static void setPAPDependencyGroups(String papDependencyGroups) throws PAPException { try { - //Now we have flattened the array into a simple comma-separated list + // Now we have flattened the array into a simple comma-separated list papDependencyGroupsFlatArray = papDependencyGroups.split("[;,]"); - //clean up the entries + // clean up the entries for (int i = 0; i < papDependencyGroupsFlatArray.length; i++) { papDependencyGroupsFlatArray[i] = papDependencyGroupsFlatArray[i].trim(); } try { - if (XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS) != null) { + if (XACMLProperties.getProperty(XacmlRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS) != null) { papIntegrityAuditPeriodSeconds = Integer.parseInt( - XACMLProperties.getProperty(XACMLRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS).trim()); + XACMLProperties.getProperty(XacmlRestProperties.PAP_INTEGRITY_AUDIT_PERIOD_SECONDS).trim()); } } catch (Exception e) { String msg = "integrity_audit_period_seconds "; LOGGER.error("\n\nERROR: " + msg + "Bad property entry: " + e.getMessage() + "\n"); PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", - " ERROR: " + msg + "Bad property entry"); + " ERROR: " + msg + "Bad property entry"); throw e; } } catch (Exception e) { @@ -446,59 +424,60 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList private static void setCommonProperties() throws PAPException { setConfigHome(); setActionHome(); - papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER); + papDbDriver = XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_DB_DRIVER); if (papDbDriver == null) { - PolicyLogger - .error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbDriver property entry"); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", + " ERROR: Bad papDbDriver property entry"); throw new PAPException("papDbDriver is null"); } setPapDbDriver(papDbDriver); - papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL); + papDbUrl = XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_DB_URL); if (papDbUrl == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbUrl property entry"); throw new PAPException("papDbUrl is null"); } setPapDbUrl(papDbUrl); - papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER); + papDbUser = XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_DB_USER); if (papDbUser == null) { - PolicyLogger - .error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbUser property entry"); + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", + " ERROR: Bad papDbUser property entry"); throw new PAPException("papDbUser is null"); } setPapDbUser(papDbUser); - papDbPassword = CryptoUtils - .decryptTxtNoExStr(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD, "")); - if (papDbPassword == null) { + PeCryptoUtils.initAesKey(XACMLProperties.getProperty(XacmlRestProperties.PROP_AES_KEY)); + papDbPd = PeCryptoUtils.decrypt(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_DB_PASSWORD)); + if (papDbPd == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", - " ERROR: Bad papDbPassword property entry"); + " ERROR: Bad papDbPassword property entry"); throw new PAPException("papDbPassword is null"); } - setPapDbPassword(papDbPassword); - papResourceName = XACMLProperties.getProperty(XACMLRestProperties.PAP_RESOURCE_NAME); + setPapDbPassword(papDbPd); + papResourceName = XACMLProperties.getProperty(XacmlRestProperties.PAP_RESOURCE_NAME); if (papResourceName == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", - " ERROR: Bad papResourceName property entry"); + " ERROR: Bad papResourceName property entry"); throw new PAPException("papResourceName is null"); } environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL"); - //Micro Service Properties + // Micro Service Properties msOnapName = XACMLProperties.getProperty("xacml.policy.msOnapName"); setMsOnapName(msOnapName); msPolicyName = XACMLProperties.getProperty("xacml.policy.msPolicyName"); setMsPolicyName(msPolicyName); - // PDPId File location - XACMLPapServlet.pdpFile = XACMLProperties.getProperty(XACMLRestProperties.PROP_PDP_IDFILE); + // PDPId File location + XACMLPapServlet.pdpFile = XACMLProperties.getProperty(XacmlRestProperties.PROP_PDP_IDFILE); if (XACMLPapServlet.pdpFile == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " The PDP Id Authentication File Property is not valid: " - + XACMLRestProperties.PROP_PDP_IDFILE); - throw new PAPException("The PDP Id Authentication File Property :" + XACMLRestProperties.PROP_PDP_IDFILE + - " is not Valid. "); + + XacmlRestProperties.PROP_PDP_IDFILE); + throw new PAPException( + "The PDP Id Authentication File Property :" + XacmlRestProperties.PROP_PDP_IDFILE + " is not Valid. "); } } /** - * Thread used only during PAP startup to initiate change messages to all known PDPs. - * This must be on a separate thread so that any GET requests from the PDPs during this update can be serviced. + * Thread used only during PAP startup to initiate change messages to all known PDPs. This must + * be on a separate thread so that any GET requests from the PDPs during this update can be + * serviced. */ @Override public void run() { @@ -508,9 +487,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see Servlet#destroy() - *

- * Depending on how this servlet is run, we may or may not care about cleaning up the resources. - * For now we assume that we do care. + *

+ * Depending on how this servlet is run, we may or may not care about cleaning up the + * resources. For now we assume that we do care. */ @Override public void destroy() { @@ -539,35 +518,31 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } + private ConsoleAndApiService getAcServiceInstance() { + return new ConsoleAndApiService(); + } + /** - * Called by: - * - PDP nodes to register themselves with the PAP, and - * - Admin Console to make changes in the PDP Groups. + * Called by: - PDP nodes to register themselves with the PAP, and - Admin Console to make + * changes in the PDP Groups. * * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); - loggingContext.transactionStarted(); - loggingContext.setServiceName("PAP.post"); - if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) { - UUID requestID = UUID.randomUUID(); - loggingContext.setRequestID(requestID.toString()); - PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPost) so we generated one"); - } else { - PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPost)"); - } - PolicyDBDaoTransaction pdpTransaction = null; - loggingContext.metricStarted(); + throws ServletException, IOException { + OnapLoggingContext loggingContext = OnapLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); + setLoggingContext(loggingContext, "doPost", "PAP.post"); + PolicyDbDaoTransaction pdpTransaction = null; try { + loggingContext.metricStarted(); im.startTransaction(); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction"); } catch (AdministrativeStateException ae) { - String message = "POST interface called for PAP " + papResourceName + " but it has an Administrative" - + " state of " + im.getStateManager().getAdminState() - + "\n Exception Message: " + PolicyUtils.CATCH_EXCEPTION; + String message = + "POST interface called for PAP " + papResourceName + " but it has an Administrative state of " + + im.getStateManager().getAdminState() + "\n Exception Message: " + PolicyUtils.CATCH_EXCEPTION; LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, ae); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction"); @@ -575,21 +550,12 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.audit("Transaction Failed - See Error.log"); setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); return; - } catch (StandbyStatusException se) { - String message = "POST interface called for PAP " + papResourceName + " but it has a Standby Status" - + " of " + im.getStateManager().getStandbyStatus() - + "\n Exception Message: " + se.getMessage(); - LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, se); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - return; - } catch (IntegrityMonitorException e) { - String message = "POST interface called for PAP " + papResourceName + " but an exception occurred" - + "\n Exception Message: " + e.getMessage(); - LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, e); + } catch (IntegrityMonitorException ime) { + String message = + "POST interface called for PAP " + papResourceName + " but it has an Administrative state of " + + im.getStateManager().getAdminState() + " and a Standby Status of " + + im.getStateManager().getStandbyStatus() + "\n Exception Message: " + ime.getMessage(); + LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, ime); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction"); loggingContext.transactionEnded(); @@ -599,18 +565,21 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } try { loggingContext.metricStarted(); - XACMLRest.dumpRequest(request); + XacmlRest.dumpRequest(request); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPost dumpRequest"); - // since getParameter reads the content string, explicitly get the content before doing that. - // Simply getting the inputStream seems to protect it against being consumed by getParameter. + // since getParameter reads the content string, explicitly get the + // content before doing that. + // Simply getting the inputStream seems to protect it against being + // consumed by getParameter. request.getInputStream(); - String groupId = request.getParameter("groupId"); + String groupId = request.getParameter(GROUPID); String apiflag = request.getParameter("apiflag"); if (groupId != null) { // Is this from the Admin Console or API? - if (apiflag != null && apiflag.equalsIgnoreCase("api")) { - // this is from the API so we need to check the client credentials before processing the request + if (apiflag != null && "api".equalsIgnoreCase(apiflag)) { + // this is from the API so we need to check the client + // credentials before processing the request if (!authorizeRequest(request)) { String message = "PEP not Authorized for making this Request!!"; PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); @@ -622,7 +591,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } loggingContext.metricStarted(); - doACPost(request, response, groupId, loggingContext); + getAcServiceInstance().doAcPost(request, response, groupId, loggingContext, papEngine); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPost doACPost"); loggingContext.transactionEnded(); @@ -643,13 +612,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList LOGGER.info("Unknown PDP: " + id); // Check PDP ID if (CheckPDP.validateID(id)) { - pdpTransaction = policyDBDao.getNewTransaction(); + pdpTransaction = policyDbDao.getNewTransaction(); try { pdpTransaction.addPdpToGroup(id, XACMLPapServlet.papEngine.getDefaultGroup().getId(), id, - "Registered on first startup", Integer.parseInt(jmxport), "PDP autoregister"); + "Registered on first startup", Integer.parseInt(jmxport), "PDP autoregister"); XACMLPapServlet.papEngine.newPDP(id, XACMLPapServlet.papEngine.getDefaultGroup(), id, - "Registered on first startup", Integer.parseInt(jmxport)); - } catch (NullPointerException | PAPException | IllegalArgumentException | IllegalStateException | PersistenceException | PolicyDBException e) { + "Registered on first startup", Integer.parseInt(jmxport)); + } catch (NullPointerException | PAPException | IllegalArgumentException | IllegalStateException + | PersistenceException | PolicyDbException e) { pdpTransaction.rollbackTransaction(); String message = "Failed to create new PDP for id: " + id; PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " " + message); @@ -682,8 +652,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList loggingContext.transactionEnded(); PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, - "PDP not Authorized to connect to this PAP. Please contact the PAP Admin for registration" + - "."); + "PDP not Authorized to connect to this PAP. Please contact the PAP Admin for registration."); PolicyLogger.audit("Transaction Failed - See Error.log"); im.endTransaction(); return; @@ -695,10 +664,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.metrics("XACMLPapServlet doPost commitTransaction"); } catch (Exception e) { PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - "Could not commit transaction to put pdp in the database"); + "Could not commit transaction to put pdp in the database"); } } - if (jmxport != null && !Objects.equals(jmxport, "")) { + if (jmxport != null && !"".equals(jmxport)) { try { ((StdPDP) pdp).setJmxPort(Integer.valueOf(jmxport)); } catch (NumberFormatException e) { @@ -708,17 +677,17 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // Get the PDP's Group OnapPDPGroup group = null; try { - group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp); + group = XACMLPapServlet.papEngine.getPDPGroup(pdp); } catch (PAPException e) { LOGGER.error(e); } if (group == null) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + - " PDP not associated with any group, even the default"); + PolicyLogger + .error(MessageCodes.ERROR_PROCESS_FLOW + " PDP not associated with any group, even the default"); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, - "PDP not associated with any group, even the default"); + "PDP not associated with any group, even the default"); im.endTransaction(); return; } @@ -739,8 +708,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // Validate the node's properties boolean isCurrent = this.isPDPCurrent(policies, pipconfig, pdpProperties); // Send back current configuration - if (isCurrent == false) { - // Tell the PDP we are sending back the current policies/pip config + if (!isCurrent) { + // Tell the PDP we are sending back the current policies/pip + // config LOGGER.info("PDP configuration NOT current."); if (policies != null) { // Put URL's into the properties in case the PDP needs to @@ -777,12 +747,6 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList LOGGER.error(e); } } - // tell the AC that something changed - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doPost notifyAC"); - loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); } catch (PAPException | IOException | NumberFormatException e) { @@ -796,7 +760,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList im.endTransaction(); return; } - //Catch anything that fell through + // Catch anything that fell through loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Ended"); im.endTransaction(); @@ -815,65 +779,38 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); - loggingContext.transactionStarted(); - loggingContext.setServiceName("PAP.get"); - if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) { - UUID requestID = UUID.randomUUID(); - loggingContext.setRequestID(requestID.toString()); - PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doGet) so we generated one"); - } else { - PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doGet)"); - } + throws ServletException, IOException { + OnapLoggingContext loggingContext = OnapLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); + setLoggingContext(loggingContext, "doGet", "PAP.get"); loggingContext.metricStarted(); - XACMLRest.dumpRequest(request); + XacmlRest.dumpRequest(request); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doGet dumpRequest"); String pathInfo = request.getRequestURI(); LOGGER.info("path info: " + pathInfo); - if (pathInfo != null) { - //DO NOT do a im.startTransaction for the test request - if (pathInfo.equals("/pap/test")) { - try { - testService(loggingContext, response); - } catch (IOException e) { - LOGGER.debug(e); - } - return; + if (pathInfo != null && "/pap/test".equals(pathInfo)) { + // DO NOT do a im.startTransaction for the test request + try { + testService(loggingContext, response); + } catch (IOException e) { + LOGGER.debug(e); } + return; } - //This im.startTransaction() covers all other Get transactions + // This im.startTransaction() covers all other Get transactions try { loggingContext.metricStarted(); im.startTransaction(); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doGet im startTransaction"); - } catch (AdministrativeStateException ae) { - String message = "GET interface called for PAP " + papResourceName + " but it has an Administrative" - + " state of " + im.getStateManager().getAdminState() - + "\n Exception Message: " + ae.getMessage(); - LOGGER.info(message, ae); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - return; - } catch (StandbyStatusException se) { - String message = "GET interface called for PAP " + papResourceName + " but it has a Standby Status" - + " of " + im.getStateManager().getStandbyStatus() - + "\n Exception Message: " + se.getMessage(); - LOGGER.info(message, se); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - return; - } catch (IntegrityMonitorException e) { - String message = "GET interface called for PAP " + papResourceName + " but an exception occurred" - + "\n Exception Message: " + e.getMessage(); - LOGGER.info(message, e); + } catch (IntegrityMonitorException ime) { + String message = + "GET interface called for PAP " + papResourceName + " but it has an Administrative state of " + + im.getStateManager().getAdminState() + " and a Standby Status of " + + im.getStateManager().getStandbyStatus() + "\n Exception Message: " + ime.getMessage(); + LOGGER.info(message, ime); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -899,7 +836,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } else { String message = - "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; + "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -909,12 +846,12 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } // Is this from the Admin Console? - String groupId = request.getParameter("groupId"); + String groupId = request.getParameter(GROUPID); if (groupId != null) { // this is from the Admin Console, so handle separately try { loggingContext.metricStarted(); - doACGet(request, response, groupId, loggingContext); + getAcServiceInstance().doAcGet(request, response, groupId, loggingContext, papEngine); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doGet doACGet"); } catch (IOException e) { @@ -938,8 +875,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // Is it known? if (pdp == null) { // Check if request came from localhost - if (request.getRemoteHost().equals("localhost") || - request.getRemoteHost().equals(request.getLocalAddr())) { + if ("localhost".equals(request.getRemoteHost()) || request.getRemoteHost().equals(request.getLocalAddr())) { // Return status information - basically all the groups loggingContext.setServiceName("PAP.getGroups"); Set groups = null; @@ -964,7 +900,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } String message = - "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr(); + "Unknown PDP: " + id + " from " + request.getRemoteHost() + " us: " + request.getLocalAddr(); PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -976,7 +912,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // Get the PDP's Group OnapPDPGroup group = null; try { - group = XACMLPapServlet.papEngine.getPDPGroup((OnapPDP) pdp); + group = XACMLPapServlet.papEngine.getPDPGroup(pdp); } catch (PAPException e) { LOGGER.error(e); } @@ -1011,14 +947,15 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } try { - LOGGER.warn("PolicyDebugging: Policy Validity: " + policy.isValid() + "\n " - + "Policy Name : " + policy.getName() + "\n Policy URI: " + policy.getLocation().toString()); + LOGGER.warn("PolicyDebugging: Policy Validity: " + policy.isValid() + "\n " + "Policy Name : " + + policy.getName() + "\n Policy URI: " + policy.getLocation().toString()); } catch (PAPException | IOException e) { LOGGER.error(e); } - try (InputStream is = new FileInputStream( - ((StdPDPGroup) group).getDirectory().toString() + File.separator + policyId); - OutputStream os = response.getOutputStream()) { + try ( + InputStream is = + new FileInputStream(((StdPDPGroup) group).getDirectory().toString() + File.separator + policyId); + OutputStream os = response.getOutputStream()) { // Send the policy back IOUtils.copy(is, os); response.setStatus(HttpServletResponse.SC_OK); @@ -1041,37 +978,21 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see HttpServlet#doPut(HttpServletRequest request, HttpServletResponse response) */ + @Override protected void doPut(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); - loggingContext.transactionStarted(); - loggingContext.setServiceName("PAP.put"); - if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) { - UUID requestID = UUID.randomUUID(); - loggingContext.setRequestID(requestID.toString()); - PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doPut) so we generated one"); - } else { - PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPut)"); - } + throws ServletException, IOException { + OnapLoggingContext loggingContext = OnapLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); + setLoggingContext(loggingContext, "doPut", "PAP.put"); try { loggingContext.metricStarted(); im.startTransaction(); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPut im startTransaction"); } catch (IntegrityMonitorException e) { - String message = "PUT interface called for PAP " + papResourceName; - if (e instanceof AdministrativeStateException) { - message += " but it has an Administrative state of " - + im.getStateManager().getAdminState(); - } else if (e instanceof StandbyStatusException) { - message += " but it has a Standby Status of " - + im.getStateManager().getStandbyStatus(); - } else { - message += " but an exception occurred"; - - } - message += "\n Exception Message: " + e.getMessage(); - + String message = + "PUT interface called for PAP " + papResourceName + " but it has an Administrative state of " + + im.getStateManager().getAdminState() + " and a Standby Status of " + + im.getStateManager().getStandbyStatus() + "\n Exception Message: " + e.getMessage(); LOGGER.info(message, e); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); @@ -1081,12 +1002,16 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } loggingContext.metricStarted(); - XACMLRest.dumpRequest(request); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doPut dumpRequest"); - //need to check if request is from the API or Admin console + // need to check if request is from the API or Admin console String apiflag = request.getParameter("apiflag"); - //This would occur if a PolicyDBDao notification was received + // For Debug purposes + if (!"api".equals(apiflag) && PolicyLogger.isDebugEnabled()) { + XacmlRest.dumpRequest(request); + PolicyLogger.metrics("XACMLPapServlet doPut dumpRequest"); + } + loggingContext.metricEnded(); + + // This would occur if a PolicyDBDao notification was received String policyDBDaoRequestUrl = request.getParameter("policydbdaourl"); if (policyDBDaoRequestUrl != null) { LOGGER.info("XACMLPapServlet: PolicyDBDao Notification received."); @@ -1102,8 +1027,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } loggingContext.metricStarted(); LOGGER.info("XACMLPapServlet: Calling PolicyDBDao to handlIncomingHttpNotification"); - policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl, policyDBDaoRequestEntityId, - policyDBDaoRequestEntityType, policyDBDaoRequestExtraData, this); + HandleIncomingNotifications handleIncomingNotifications = new HandleIncomingNotifications(); + handleIncomingNotifications.handleIncomingHttpNotification(policyDBDaoRequestUrl, + policyDBDaoRequestEntityId, policyDBDaoRequestEntityType, policyDBDaoRequestExtraData, this); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doPut handle incoming http notification"); response.setStatus(200); @@ -1131,7 +1057,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } else { String message = - "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; + "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -1160,16 +1086,16 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } /* - * This is to update the PDP Group with the policy/policies being pushed - * Part of a 2 step process to push policies to the PDP that can now be done - * From both the Admin Console and the PolicyEngine API + * This is to update the PDP Group with the policy/policies being pushed Part of a 2 step + * process to push policies to the PDP that can now be done From both the Admin Console and + * the PolicyEngine API */ - String groupId = request.getParameter("groupId"); + String groupId = request.getParameter(GROUPID); if (groupId != null) { if (apiflag != null) { if (!authorizeRequest(request)) { String message = - "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; + "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -1191,7 +1117,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // this is from the Admin Console, so handle separately try { loggingContext.metricEnded(); - doACPut(request, response, groupId, loggingContext); + getAcServiceInstance().doAcPut(request, response, groupId, loggingContext, papEngine); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet goPut doACPut"); } catch (IOException e) { @@ -1260,47 +1186,22 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see HttpServlet#doDelete(HttpServletRequest request, HttpServletResponse response) */ + @Override protected void doDelete(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - ONAPLoggingContext loggingContext = ONAPLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); - loggingContext.transactionStarted(); - loggingContext.setServiceName("PAP.delete"); - if ((loggingContext.getRequestID() == null) || (Objects.equals(loggingContext.getRequestID(), ""))) { - UUID requestID = UUID.randomUUID(); - loggingContext.setRequestID(requestID.toString()); - PolicyLogger.info("requestID not provided in call to XACMLPapSrvlet (doDelete) so we generated one"); - } else { - PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doDelete)"); - } + throws ServletException, IOException { + OnapLoggingContext loggingContext = OnapLoggingUtils.getLoggingContextForRequest(request, baseLoggingContext); + setLoggingContext(loggingContext, "doDelete", "PAP.delete"); try { loggingContext.metricStarted(); im.startTransaction(); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doDelete im startTransaction"); - } catch (AdministrativeStateException ae) { - String message = "DELETE interface called for PAP " + papResourceName + " but it has an Administrative" - + " state of " + im.getStateManager().getAdminState() - + "\n Exception Message: " + ae.getMessage(); - LOGGER.info(message, ae); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - return; - } catch (StandbyStatusException se) { - String message = "PUT interface called for PAP " + papResourceName + " but it has a Standby Status" - + " of " + im.getStateManager().getStandbyStatus() - + "\n Exception Message: " + se.getMessage(); - LOGGER.info(message, se); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - return; - } catch (IntegrityMonitorException e) { - String message = "PUT interface called for PAP " + papResourceName + " but an exception occurred" - + "\n Exception Message: " + e.getMessage(); - LOGGER.info(message, e); + } catch (IntegrityMonitorException ime) { + String message = + "DELETE interface called for PAP " + papResourceName + " but it has an Administrative state of " + + im.getStateManager().getAdminState() + " and a Standby Status of " + + im.getStateManager().getStandbyStatus() + "\n Exception Message: " + ime.getMessage(); + LOGGER.info(message, ime); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -1308,17 +1209,17 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } loggingContext.metricStarted(); - XACMLRest.dumpRequest(request); + XacmlRest.dumpRequest(request); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doDelete dumpRequest"); - String groupId = request.getParameter("groupId"); + String groupId = request.getParameter(GROUPID); String apiflag = request.getParameter("apiflag"); if (groupId != null) { // Is this from the Admin Console or API? if (apiflag != null) { if (!authorizeRequest(request)) { String message = - "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; + "PEP not Authorized for making this Request!! \n Contact Administrator for this Scope. "; PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -1342,7 +1243,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // this is from the Admin Console, so handle separately try { loggingContext.metricStarted(); - doACDelete(request, response, groupId, loggingContext); + getAcServiceInstance().doAcDelete(request, response, groupId, loggingContext, papEngine); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet doDelete doACDelete"); } catch (IOException e) { @@ -1353,7 +1254,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList im.endTransaction(); return; } - //Catch anything that fell through + // Catch anything that fell through PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Request does not have groupId"); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); @@ -1365,8 +1266,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList String localRootPolicies = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES); String localReferencedPolicies = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); if (localRootPolicies == null || localReferencedPolicies == null) { - LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing property on PAP server: RootPolicies=" + - localRootPolicies + " ReferencedPolicies=" + localReferencedPolicies); + LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing property on PAP server: RootPolicies=" + + localRootPolicies + " ReferencedPolicies=" + localReferencedPolicies); return false; } // Compare the policies and pipconfig properties to the pdpProperties @@ -1375,22 +1276,26 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // xacml.referencedPolicies without any .url entries Properties pdpPolicies = XACMLProperties.getPolicyProperties(pdpProperties, false); Properties pdpPipConfig = XACMLProperties.getPipProperties(pdpProperties); - if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) && - localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) && - pdpPipConfig.equals(pipconfig)) { + if (localRootPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_ROOTPOLICIES)) + && localReferencedPolicies.equals(pdpPolicies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES)) + && pdpPipConfig.equals(pipconfig)) { // The PDP is current return true; } } catch (Exception e) { - // we get here if the PDP did not include either xacml.rootPolicies or xacml.pip.engines, - // or if there are policies that do not have a corresponding ".url" property. - // Either of these cases means that the PDP is not up-to-date, so just drop-through to return false. + // we get here if the PDP did not include either xacml.rootPolicies + // or xacml.pip.engines, + // or if there are policies that do not have a corresponding ".url" + // property. + // Either of these cases means that the PDP is not up-to-date, so + // just drop-through to return false. PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPapServlet", " PDP Error"); } return false; } - private void populatePolicyURL(StringBuffer urlPath, Properties policies) { + @VisibleForTesting + protected void populatePolicyURL(StringBuffer urlPath, Properties policies) { String lists[] = new String[2]; lists[0] = policies.getProperty(XACMLProperties.PROP_ROOTPOLICIES); lists[1] = policies.getProperty(XACMLProperties.PROP_REFERENCEDPOLICIES); @@ -1406,7 +1311,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } protected String getPDPID(HttpServletRequest request) { - String pdpURL = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_ID); + String pdpURL = request.getHeader(XacmlRestProperties.PROP_PDP_HTTP_HEADER_ID); if (pdpURL == null || pdpURL.isEmpty()) { // Should send back its port for identification LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP did not send custom header"); @@ -1416,11 +1321,11 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } protected String getPDPJMX(HttpServletRequest request) { - String pdpJMMX = request.getHeader(XACMLRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT); + String pdpJMMX = request.getHeader(XacmlRestProperties.PROP_PDP_HTTP_HEADER_JMX_PORT); if (pdpJMMX == null || pdpJMMX.isEmpty()) { // Should send back its port for identification - LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + - "PDP did not send custom header for JMX Port so the value of 0 is assigned"); + LOGGER.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + + "PDP did not send custom header for JMX Port so the value of 0 is assigned"); return null; } return pdpJMMX; @@ -1437,11 +1342,13 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList * @throws IOException */ public void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws IOException { - PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction(); + OnapLoggingContext loggingContext) throws IOException { + PolicyDbDaoTransaction acPutTransaction = policyDbDao.getNewTransaction(); PolicyLogger.audit("PolicyDBDaoTransaction started for updateGroupsFromAPI"); try { - // for PUT operations the group may or may not need to exist before the operation can be done + String userId = request.getParameter("userId"); + // for PUT operations the group may or may not need to exist before + // the operation can be done StdPDPGroup group = (StdPDPGroup) papEngine.getGroup(groupId); // get the request input stream content into a String @@ -1456,14 +1363,13 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // convert Object sent as JSON into local object StdPDPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPDPPolicy.class); - //Get the current policies from the Group and Add the new one - Set currentPoliciesInGroup = new HashSet<>(); - currentPoliciesInGroup = group.getPolicies(); - //If the selected policy is in the group we must remove the old version of it + // Get the current policies from the Group and Add the new one + // If the selected policy is in the group we must remove the old + // version of it LOGGER.info("Removing old version of the policy"); - for (PDPPolicy existingPolicy : currentPoliciesInGroup) { - if (existingPolicy.getName().equals(policy.getName()) && - !existingPolicy.getId().equals(policy.getId())) { + for (PDPPolicy existingPolicy : group.getPolicies()) { + if (existingPolicy.getName().equals(policy.getName()) + && !existingPolicy.getId().equals(policy.getId())) { group.removePolicy(existingPolicy); LOGGER.info("Removing policy: " + existingPolicy); break; @@ -1473,11 +1379,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // Assume that this is an update of an existing PDP Group loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup"); try { - acPutTransaction.updateGroup(group, "XACMLPapServlet.doACPut"); + acPutTransaction.updateGroup(group, "XACMLPapServlet.doACPut", userId); } catch (Exception e) { PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Error while updating group in the database: " - + "group=" + group.getId()); + " Error while updating group in the database: " + "group=" + group.getId()); throw new PAPException(e.getMessage()); } @@ -1496,7 +1401,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList response.setStatus(HttpServletResponse.SC_NO_CONTENT); response.addHeader("operation", "push"); response.addHeader("policyId", policyId); - response.addHeader("groupId", groupId); + response.addHeader(GROUPID, groupId); LOGGER.info("Group '" + group.getId() + "' updated"); @@ -1504,18 +1409,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList acPutTransaction.commitTransaction(); loggingContext.metricEnded(); PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction"); - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI notifyAC"); // Group changed, which might include changing the policies groupChanged(group, loggingContext); loggingContext.transactionEnded(); LOGGER.info("Success"); - if (policy != null && - ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param")))) { + if (policy != null + && ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param")))) { PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance(); if (pushPolicyHandler.preSafetyCheck(policy, configHome)) { LOGGER.debug("Precheck Successful."); @@ -1523,1429 +1424,153 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } PolicyLogger.audit("Transaction Ended Successfully"); + return; } catch (PAPException e) { acPutTransaction.rollbackTransaction(); PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception"); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); - String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + - "Exception in request to update group from API - See Error.log on on the PAP."; + String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + + "Exception in request to update group from API - See Error.log on on the PAP."; setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.addHeader("error", ADD_GROUP_ERROR); response.addHeader("message", message); + return; } } - /** - * Requests from the Admin Console for operations not on single specific objects - * - * @param request - * @param response - * @param groupId - * @param loggingContext - * @throws ServletException - * @throws IOException + /* + * HELPER to change Group status when PDP status is changed (Must NOT be called from a method + * that is synchronized on the papEngine or it may deadlock) */ - private void doACPost(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws ServletException, IOException { - PolicyDBDaoTransaction doACPostTransaction = null; - try { - String groupName = request.getParameter("groupName"); - String groupDescription = request.getParameter("groupDescription"); - String apiflag = request.getParameter("apiflag"); - if (groupName != null && groupDescription != null) { - // Args: group= groupName= groupDescription= <= create - // a new group - loggingContext.setServiceName("AC:PAP.createGroup"); - String unescapedName = null; - String unescapedDescription = null; - try { - unescapedName = URLDecoder.decode(groupName, "UTF-8"); - unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8"); - } catch (UnsupportedEncodingException e) { - LOGGER.error(e); - } - PolicyDBDaoTransaction newGroupTransaction = policyDBDao.getNewTransaction(); - try { - newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName, - unescapedDescription, "XACMLPapServlet.doACPost"); - papEngine.newGroup(unescapedName, unescapedDescription); - loggingContext.metricStarted(); - newGroupTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction"); - } catch (Exception e) { - newGroupTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Unable to create new group"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Unable to create new group '" + groupId + "'"); - return; - } - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("New Group '" + groupId + "' created"); - } - // tell the Admin Consoles there is a change - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC"); - // new group by definition has no PDPs, so no need to notify them of changes - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } - // for all remaining POST operations the group must exist before the operation can be done - OnapPDPGroup group = null; - try { - group = papEngine.getGroup(groupId); - } catch (PAPException e) { - LOGGER.error(e); - } - if (group == null) { - String message = "Unknown groupId '" + groupId + "'"; - //for fixing Header Manipulation of Fortify issue - if (!message.matches(REGEX)) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.addHeader("error", ADD_GROUP_ERROR); - response.addHeader("message", "GroupId Id is not valid"); - return; - } - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - if (apiflag != null) { - response.addHeader("error", "unknownGroupId"); - response.addHeader("operation", "push"); - response.addHeader("message", message); - response.setStatus(HttpServletResponse.SC_NOT_FOUND); - } else { - setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message); - } - return; + public void setPDPSummaryStatus(OnapPDP pdp, PDPStatus.Status newStatus) throws PAPException { + setPDPSummaryStatus(pdp, newStatus.toString()); + } + + public void setPDPSummaryStatus(OnapPDP pdp, String newStatus) throws PAPException { + synchronized (papEngine) { + StdPDPStatus status = new StdPDPStatus(); + status.setStatus(PDPStatus.Status.valueOf(newStatus)); + ((StdPDP) pdp).setStatus(status); + // now adjust the group + StdPDPGroup group = (StdPDPGroup) papEngine.getPDPGroup(pdp); + // if the PDP was just deleted it may transiently exist but not be + // in a group + if (group != null) { + group.resetStatus(); } + } + } - // If the request contains a policyId then we know we are pushing the policy to PDP - if (request.getParameter("policyId") != null) { + /* + * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine in + * the PDP group directories + */ + @Override + public void changed() { + // all PDPs in all groups need to be updated/sync'd + Set groups; + try { + groups = papEngine.getOnapPDPGroups(); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed"); + throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e); + } + for (OnapPDPGroup group : groups) { + groupChanged(group); + } + } - if (apiflag != null) { - loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy"); - LOGGER.info("PushPolicy Request From The API"); - } else { - loggingContext.setServiceName("AC:PAP.postPolicy"); - LOGGER.info("PushPolicy Request From The AC"); - } + public void changed(OnapLoggingContext loggingContext) { + // all PDPs in all groups need to be updated/sync'd + Set groups; + try { + groups = papEngine.getOnapPDPGroups(); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed"); + throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e); + } + for (OnapPDPGroup group : groups) { + groupChanged(group, loggingContext); + } + } - String policyId = request.getParameter("policyId"); - PolicyDBDaoTransaction addPolicyToGroupTransaction = policyDBDao.getNewTransaction(); - StdPDPGroup updatedGroup = null; - try { - //Copying the policy to the file system and updating groups in database - LOGGER.info("PapServlet: calling PolicyDBDao.addPolicyToGroup()"); - updatedGroup = addPolicyToGroupTransaction - .addPolicyToGroup(group.getId(), policyId, "XACMLPapServlet.doACPost"); - loggingContext.metricStarted(); - addPolicyToGroupTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction"); - LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed"); + @Override + public void groupChanged(OnapPDPGroup group) { + // all PDPs within one group need to be updated/sync'd + for (OnapPDP pdp : group.getOnapPdps()) { + pdpChanged(pdp, getPdpDataByGroup(group)); + } + } - } catch (Exception e) { - addPolicyToGroupTransaction.rollbackTransaction(); - String message = "Policy '" + policyId + "' not copied to group '" + groupId + "': " + e; - //for fixing Header Manipulation of Fortify issue - if (!message.matches(REGEX)) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.addHeader("error", ADD_GROUP_ERROR); - response.addHeader("message", "Policy Id is not valid"); - return; - } - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - if (apiflag != null) { - response.addHeader("error", "policyCopyError"); - response.addHeader("message", message); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } else { - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); - } - return; - } + public void groupChanged(OnapPDPGroup group, OnapLoggingContext loggingContext) { + // all PDPs within one group need to be updated/sync'd + for (OnapPDP pdp : group.getOnapPdps()) { + pdpChanged(pdp, loggingContext, getPdpDataByGroup(group)); + } + } - if (apiflag != null) { - /* - * If request comes from the API we need to run the PolicyDBDao updateGroup() to notify other - * paps of the change. - * The GUI does this from the POLICY-SDK-APP code. - */ + @Override + public void pdpChanged(OnapPDP pdp) { + // kick off a thread to do an event notification for each PDP. + // This needs to be on a separate thread so that PDPs that do not + // respond (down, non-existent, etc) + // do not block the PSP response to the AC, which would freeze the GUI + // until all PDPs sequentially respond or time-out. + Thread t = new Thread(new UpdatePdpThread(pdp, getPdpDataByPdpId(pdp))); + if (CheckPDP.validateID(pdp.getId())) { + t.start(); + } + } - // Get new transaction to perform updateGroup() - PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction(); - try { - // get the request content into a String and read the inputStream into a buffer - java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); - scanner.useDelimiter("\\A"); - String json = scanner.hasNext() ? scanner.next() : ""; - scanner.close(); - - // convert Object sent as JSON into local object - ObjectMapper mapper = new ObjectMapper(); - Object objectFromJSON = mapper.readValue(json, StdPDPPolicy.class); - StdPDPPolicy policy = (StdPDPPolicy) objectFromJSON; - - LOGGER.info("Request JSON Payload: " + json); - - // Assume that this is an update of an existing PDP Group - loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup"); - try { - acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut"); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Error occurred when notifying PAPs of a group change: " - + e); - throw new PAPException(e.getMessage()); - } + public void pdpChanged(OnapPDP pdp, OnapLoggingContext loggingContext) { + // kick off a thread to do an event notification for each PDP. + // This needs to be on a separate thread so that PDPs that do not + // respond (down, non-existent, etc) + // do not block the PSP response to the AC, which would freeze the GUI + // until all PDPs sequentially respond or time-out. + Thread t = new Thread(new UpdatePdpThread(pdp, loggingContext, getPdpDataByPdpId(pdp))); + if (CheckPDP.validateID(pdp.getId())) { + t.start(); + } + } - LOGGER.info("Calling updatGroup() with new group"); - papEngine.updateGroup(updatedGroup); - - LOGGER.info("Group '" + updatedGroup.getId() + "' updated"); - - // Commit transaction to send notification to other PAPs - loggingContext.metricStarted(); - acPutTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction"); - loggingContext.metricStarted(); - - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI notifyAC"); - - // Group changed to send notification to PDPs, which might include changing the policies - groupChanged(updatedGroup, loggingContext); - loggingContext.transactionEnded(); - LOGGER.info("Success"); - - if (policy != null && ((policy.getName().contains("Config_MS_")) || - (policy.getId().contains("BRMS_Param")))) { - PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance(); - if (pushPolicyHandler.preSafetyCheck(policy, configHome)) { - LOGGER.debug("Precheck Successful."); - } - } - - //delete temporary policy file from the bin directory - Files.deleteIfExists(Paths.get(policy.getId())); - - } catch (Exception e) { - acPutTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " API PUT exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + - "Exception occurred when updating the group from API."; - LOGGER.error(message); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.addHeader("error", ADD_GROUP_ERROR); - response.addHeader("message", message); - return; - } - } - - // policy file copied ok and the Group was updated on the PDP - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - response.addHeader("operation", "push"); - response.addHeader("policyId", policyId); - response.addHeader("groupId", groupId); - - LOGGER.info("policy '" + policyId + "' copied to directory for group '" + groupId + "'"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - LOGGER.info("Transaction Ended Successfully"); - - } else if (request.getParameter("default") != null) { - // Args: group= default=true <= make default - // change the current default group to be the one identified in the request. - loggingContext.setServiceName("AC:PAP.setDefaultGroup"); - // This is a POST operation rather than a PUT "update group" because of the side-effect that the - // current default group is also changed. - // It should never be the case that multiple groups are currently marked as the default, but protect - // against that anyway. - PolicyDBDaoTransaction setDefaultGroupTransaction = policyDBDao.getNewTransaction(); - try { - setDefaultGroupTransaction.changeDefaultGroup(group, "XACMLPapServlet.doACPost"); - papEngine.setDefaultGroup(group); - loggingContext.metricStarted(); - setDefaultGroupTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction"); - } catch (Exception e) { - setDefaultGroupTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Unable to set group"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Unable to set group '" + groupId + "' to default"); - return; - } - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Group '" + groupId + "' set to be default"); - } - // Notify the Admin Consoles that something changed - // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just - // notify on that - //TODO - Future: FIGURE OUT WHAT LEVEL TO NOTIFY: 2 groups or entire set - currently notify AC to - // update whole configuration of all groups - loggingContext.metricStarted(); - notifyAC(); - // This does not affect any PDPs in the existing groups, so no need to notify them of this change - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - LOGGER.info("Transaction Ended Successfully"); - } else if (request.getParameter("pdpId") != null) { - doACPostTransaction = policyDBDao.getNewTransaction(); - // Args: group= pdpId= <= move PDP to group - loggingContext.setServiceName("AC:PAP.movePDP"); - String pdpId = request.getParameter("pdpId"); - OnapPDP pdp = papEngine.getPDP(pdpId); - OnapPDPGroup originalGroup = papEngine.getPDPGroup((OnapPDP) pdp); - try { - doACPostTransaction.movePdp(pdp, group, "XACMLPapServlet.doACPost"); - } catch (Exception e) { - doACPostTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Error while moving pdp in the database: " - + "pdp=" + pdp.getId() + ",to group=" + group.getId()); - throw new PAPException(e.getMessage()); - } - papEngine.movePDP((OnapPDP) pdp, group); - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("PDP '" + pdp.getId() + "' moved to group '" + group.getId() + "' set to be default"); - } - // update the status of both the original group and the new one - ((StdPDPGroup) originalGroup).resetStatus(); - ((StdPDPGroup) group).resetStatus(); - // Notify the Admin Consoles that something changed - // For now the AC cannot handle anything more detailed than the whole set of PDPGroups, so just - // notify on that - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost notifyAC"); - // Need to notify the PDP that it's config may have changed - pdpChanged(pdp, loggingContext); - loggingContext.metricStarted(); - doACPostTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC POST exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - /** - * Requests from the Admin Console to GET info about the Groups and PDPs - * - * @param request - * @param response - * @param groupId - * @param loggingContext - * @throws ServletException - * @throws IOException - */ - private void doACGet(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws IOException { - try { - String parameterDefault = request.getParameter("default"); - String pdpId = request.getParameter("pdpId"); - String pdpGroup = request.getParameter("getPDPGroup"); - if ("".equals(groupId)) { - // request IS from AC but does not identify a group by name - if (parameterDefault != null) { - // Request is for the Default group (whatever its id) - loggingContext.setServiceName("AC:PAP.getDefaultGroup"); - OnapPDPGroup group = papEngine.getDefaultGroup(); - // convert response object to JSON and include in the response - mapperWriteValue(new ObjectMapper(), response, group); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'"); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("content-type", "application/json"); - try { - response.getOutputStream().close(); - } catch (IOException e) { - LOGGER.error(e); - } - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } else if (pdpId != null) { - // Request is related to a PDP - if (pdpGroup == null) { - // Request is for the (unspecified) group containing a given PDP - loggingContext.setServiceName("AC:PAP.getPDP"); - OnapPDP pdp = null; - try { - pdp = papEngine.getPDP(pdpId); - } catch (PAPException e) { - LOGGER.error(e); - } - // convert response object to JSON and include in the response - mapperWriteValue(new ObjectMapper(), response, pdp); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'"); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("content-type", "application/json"); - try { - response.getOutputStream().close(); - } catch (IOException e) { - LOGGER.error(e); - } - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } else { - // Request is for the group containing a given PDP - loggingContext.setServiceName("AC:PAP.getGroupForPDP"); - OnapPDPGroup group = null; - try { - OnapPDP pdp = papEngine.getPDP(pdpId); - group = papEngine.getPDPGroup((OnapPDP) pdp); - } catch (PAPException e) { - LOGGER.error(e); - } - // convert response object to JSON and include in the response - mapperWriteValue(new ObjectMapper(), response, group); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'"); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("content-type", "application/json"); - try { - response.getOutputStream().close(); - } catch (IOException e) { - LOGGER.error(e); - } - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } - } else { - // request is for top-level properties about all groups - loggingContext.setServiceName("AC:PAP.getAllGroups"); - Set groups = null; - try { - groups = papEngine.getOnapPDPGroups(); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - return; - } - // convert response object to JSON and include in the response - mapperWriteValue(new ObjectMapper(), response, groups); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("GET All groups req"); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("content-type", "application/json"); - try { - response.getOutputStream().close(); - } catch (IOException e) { - LOGGER.error(e); - } - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } - } - // for all other GET operations the group must exist before the operation can be done - OnapPDPGroup group = null; - try { - group = papEngine.getGroup(groupId); - } catch (PAPException e) { - LOGGER.error(e); - } - if (group == null) { - String message = "Unknown groupId '" + groupId + "'"; - //for fixing Header Manipulation of Fortify issue - if (!message.matches(REGEX)) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.addHeader("error", ADD_GROUP_ERROR); - response.addHeader("message", "Group Id is not valid"); - return; - } - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message); - return; - } - // Figure out which request this is based on the parameters - String policyId = request.getParameter("policyId"); - if (policyId != null) { - // retrieve a policy - loggingContext.setServiceName("AC:PAP.getPolicy"); - // convert response object to JSON and include in the response - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented"); - } else { - // No other parameters, so return the identified Group - loggingContext.setServiceName("AC:PAP.getGroup"); - // convert response object to JSON and include in the response - mapperWriteValue(new ObjectMapper(), response, group); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'"); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("content-type", "application/json"); - try { - response.getOutputStream().close(); - } catch (IOException e) { - LOGGER.error(e); - } - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - return; - } - // Currently there are no other GET calls from the AC. - // The AC uses the "GET All Groups" operation to fill its local cache and uses that cache for all other - // GETs without calling the PAP. - // Other GETs that could be called: - // Specific Group (groupId=) - // A Policy (groupId= policyId=) - // A PDP (groupId= pdpId=) - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED "); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC Get exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - /** - * Requests from the Admin Console to create new items or update existing ones - * - * @param request - * @param response - * @param groupId - * @param loggingContext - * @throws ServletException - * @throws IOException - */ - private void doACPut(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws IOException { - PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction(); - try { - // for PUT operations the group may or may not need to exist before the operation can be done - OnapPDPGroup group = papEngine.getGroup(groupId); - // determine the operation needed based on the parameters in the request - // for remaining operations the group must exist before the operation can be done - if (group == null) { - String message = "Unknown groupId '" + groupId + "'"; - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message); - return; - } - if (request.getParameter("policy") != null) { - // group= policy= contents=policy file <= Create new policy - // file in group dir, or replace it if it already exists (do not touch properties) - loggingContext.setServiceName("AC:PAP.putPolicy"); - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + - " PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! "); - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } else if (request.getParameter("pdpId") != null) { - // ARGS: group= pdpId= <= create a new PDP or Update an Existing one - String pdpId = request.getParameter("pdpId"); - if (papEngine.getPDP(pdpId) == null) { - loggingContext.setServiceName("AC:PAP.createPDP"); - } else { - loggingContext.setServiceName("AC:PAP.updatePDP"); - } - // get the request content into a String - String json = null; - // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file) - try { - Scanner scanner = new Scanner(request.getInputStream()); - scanner.useDelimiter("\\A"); - json = scanner.hasNext() ? scanner.next() : ""; - scanner.close(); - } catch (IOException e) { - LOGGER.error(e); - } - LOGGER.info("JSON request from AC: " + json); - // convert Object sent as JSON into local object - ObjectMapper mapper = new ObjectMapper(); - Object objectFromJSON = null; - try { - objectFromJSON = mapper.readValue(json, StdPDP.class); - } catch (Exception e) { - LOGGER.error(e); - } - if (pdpId == null || - objectFromJSON == null || - !(objectFromJSON instanceof StdPDP) || - ((StdPDP) objectFromJSON).getId() == null || - !((StdPDP) objectFromJSON).getId().equals(pdpId)) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId + - " objectFromJSON=" + objectFromJSON); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Bad input pdpid for object:" + objectFromJSON); - } - StdPDP pdp = (StdPDP) objectFromJSON; - if (pdp != null) { - OnapPDP oPDP = null; - try { - oPDP = papEngine.getPDP(pdpId); - } catch (PAPException e) { - LOGGER.error(e); - } - if (oPDP == null) { - // this is a request to create a new PDP object - try { - acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(), - pdp.getDescription(), pdp.getJmxPort(), "XACMLPapServlet.doACPut"); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Error while adding pdp to group in the database: " - + "pdp=" + (pdp.getId()) + ",to group=" + group.getId()); - throw new PAPException(e.getMessage()); - } - try { - papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort()); - } catch (PAPException e) { - LOGGER.error(e); - } - } else { - try { - acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut"); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - " Error while updating pdp in the database: " - + "pdp=" + pdp.getId()); - throw new PAPException(e.getMessage()); - } - // this is a request to update the pdp - try { - papEngine.updatePDP(pdp); - } catch (PAPException e) { - LOGGER.error(e); - } - } - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("PDP '" + pdpId + "' created/updated"); - } - // adjust the group's state including the new PDP - ((StdPDPGroup) group).resetStatus(); - // tell the Admin Consoles there is a change - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC"); - // this might affect the PDP, so notify it of the change - pdpChanged(pdp, loggingContext); - loggingContext.metricStarted(); - acPutTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } else { - try { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, "XACMLPapServlet", - " Error while adding pdp to group in the database: " - + "pdp=null" + ",to group=" + group.getId()); - throw new PAPException("PDP is null"); - } catch (Exception e) { - throw new PAPException("PDP is null" + e.getMessage() + e); - } - } - } else if (request.getParameter("pipId") != null) { - // group= pipId= contents=pip properties <= add a - // PIP to pip config, or replace it if it already exists (lenient operation) - loggingContext.setServiceName("AC:PAP.putPIP"); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); - } else { - // Assume that this is an update of an existing PDP Group - // ARGS: group= <= Update an Existing Group - loggingContext.setServiceName("AC:PAP.updateGroup"); - // get the request content into a String - String json = null; - // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file) - try { - Scanner scanner = new Scanner(request.getInputStream()); - scanner.useDelimiter("\\A"); - json = scanner.hasNext() ? scanner.next() : ""; - scanner.close(); - } catch (IOException e) { - LOGGER.error(e); - } - LOGGER.info("JSON request from AC: " + json); - // convert Object sent as JSON into local object - ObjectMapper mapper = new ObjectMapper(); - Object objectFromJSON = null; - try { - objectFromJSON = mapper.readValue(json, StdPDPGroup.class); - } catch (Exception e) { - LOGGER.error(e); - } - if (objectFromJSON == null || !(objectFromJSON instanceof StdPDPGroup) || - !((StdPDPGroup) objectFromJSON).getId().equals(group.getId())) { - PolicyLogger - .error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + group.getId() + - " objectFromJSON=" + objectFromJSON); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Bad input id for object:" + objectFromJSON); - } - // The Path on the PAP side is not carried on the RESTful interface with the AC - // (because it is local to the PAP) - // so we need to fill that in before submitting the group for update - if (objectFromJSON != null) { - ((StdPDPGroup) objectFromJSON).setDirectory(((StdPDPGroup) group).getDirectory()); - } - try { - if ("delete".equals(((StdPDPGroup) objectFromJSON).getOperation())) { - acPutTransaction.updateGroup((StdPDPGroup) objectFromJSON, "XACMLPapServlet.doDelete"); - } else { - acPutTransaction.updateGroup((StdPDPGroup) objectFromJSON, "XACMLPapServlet.doACPut"); - } - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: " - + "group=" + group.getId()); - LOGGER.error(e); - throw new PAPException(e.getMessage()); - } - - PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance(); - OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJSON; - if (pushPolicyHandler.preSafetyCheck(updatedGroup, configHome)) { - LOGGER.debug("Precheck Successful."); - } - try { - papEngine.updateGroup((StdPDPGroup) objectFromJSON); - } catch (PAPException e) { - LOGGER.error(e); - } - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Group '" + group.getId() + "' updated"); - } - loggingContext.metricStarted(); - acPutTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); - // tell the Admin Consoles there is a change - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC"); - // Group changed, which might include changing the policies - groupChanged(group, loggingContext); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } - } catch (PAPException e) { - LOGGER.debug(e); - acPutTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC PUT exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - /** - * Requests from the Admin Console to delete/remove items - * - * @param request - * @param response - * @param groupId - * @param loggingContext - * @throws ServletException - * @throws IOException - */ - private void doACDelete(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws IOException { - PolicyDBDaoTransaction removePdpOrGroupTransaction = policyDBDao.getNewTransaction(); - try { - // for all DELETE operations the group must exist before the operation can be done - loggingContext.setServiceName("AC:PAP.delete"); - OnapPDPGroup group = papEngine.getGroup(groupId); - if (group == null) { - String message = "Unknown groupId '" + groupId + "'"; - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId + "'"); - return; - } - // determine the operation needed based on the parameters in the request - if (request.getParameter("policy") != null) { - // group= policy= [delete=] <= delete policy file from - // group - loggingContext.setServiceName("AC:PAP.deletePolicy"); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); - } else if (request.getParameter("pdpId") != null) { - // ARGS: group= pdpId= <= delete PDP - String pdpId = request.getParameter("pdpId"); - OnapPDP pdp = papEngine.getPDP(pdpId); - try { - removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete"); - } catch (Exception e) { - throw new PAPException(e); - } - try { - papEngine.removePDP((OnapPDP) pdp); - } catch (PAPException e) { - LOGGER.error(e); - } - // adjust the status of the group, which may have changed when we removed this PDP - ((StdPDPGroup) group).resetStatus(); - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC"); - // update the PDP and tell it that it has NO Policies (which prevents it from serving PEP Requests) - pdpChanged(pdp, loggingContext); - loggingContext.metricStarted(); - removePdpOrGroupTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } else if (request.getParameter("pipId") != null) { - // group= pipId= <= delete PIP config for given engine - loggingContext.setServiceName("AC:PAP.deletePIPConfig"); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); - } else { - // ARGS: group= movePDPsToGroupId= <= delete a group and - // move all its PDPs to the given group - String moveToGroupId = request.getParameter("movePDPsToGroupId"); - OnapPDPGroup moveToGroup = null; - if (moveToGroupId != null) { - try { - moveToGroup = papEngine.getGroup(moveToGroupId); - } catch (PAPException e) { - LOGGER.error(e); - } - } - // get list of PDPs in the group being deleted so we can notify them that they got changed - Set movedPDPs = new HashSet<>(); - movedPDPs.addAll(group.getOnapPdps()); - // do the move/remove - try { - removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete"); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, "XACMLPapServlet", - " Failed to delete PDP Group. Exception"); - throw new PAPException(e.getMessage()); - } - try { - papEngine.removeGroup(group, moveToGroup); - } catch (PAPException e) { - LOGGER.error(e); - } - response.setStatus(HttpServletResponse.SC_NO_CONTENT); - loggingContext.metricStarted(); - notifyAC(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut notifyAC"); - // notify any PDPs in the removed set that their config may have changed - for (OnapPDP pdp : movedPDPs) { - pdpChanged(pdp, loggingContext); - } - loggingContext.metricStarted(); - removePdpOrGroupTransaction.commitTransaction(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); - loggingContext.transactionEnded(); - auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); - } - } catch (PAPException e) { - removePdpOrGroupTransaction.rollbackTransaction(); - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " AC DELETE exception"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed - See Error.log"); - setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - /** - * Heartbeat thread - periodically check on PDPs' status - *

- * Heartbeat with all known PDPs. - *

- * Implementation note: - *

- * The PDPs are contacted Sequentially, not in Parallel. - *

- * If we did this in parallel using multiple threads we would simultaneously use - * - 1 thread and - * - 1 connection - * for EACH PDP. - * This could become a resource problem since we already use multiple threads and connections for updating the PDPs - * when user changes occur. - * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive. - *

- * The Sequential operation does a heartbeat request to each PDP one at a time. - * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they - * timeout. - * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds) - * it could take a long time to cycle through all of the PDPs. - * That means that this may not notice a PDP being down in a predictable time. - */ - private class Heartbeat implements Runnable { - private PAPPolicyEngine papEngine; - private Set pdps = new HashSet<>(); - private int heartbeatInterval; - private int heartbeatTimeout; - - public volatile boolean isRunning = false; - - public synchronized boolean isRunning() { - return this.isRunning; - } - - public synchronized void terminate() { - this.isRunning = false; - } - - public Heartbeat(PAPPolicyEngine papEngine2) { - papEngine = papEngine2; - this.heartbeatInterval = Integer.parseInt( - XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_INTERVAL, "10000")); - this.heartbeatTimeout = Integer.parseInt( - XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_HEARTBEAT_TIMEOUT, "10000")); - } - - @Override - public void run() { - // Set ourselves as running - synchronized (this) { - this.isRunning = true; - } - HashMap idToURLMap = new HashMap<>(); - try { - while (this.isRunning()) { - // Wait the given time - Thread.sleep(heartbeatInterval); - // get the list of PDPs (may have changed since last time) - pdps.clear(); - synchronized (papEngine) { - try { - for (OnapPDPGroup g : papEngine.getOnapPDPGroups()) { - for (OnapPDP p : g.getOnapPdps()) { - pdps.add(p); - } - } - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - "Heartbeat unable to read PDPs from PAPEngine"); - } - } - // Check for shutdown - if (this.isRunning() == false) { - LOGGER.info("isRunning is false, getting out of loop."); - break; - } - // try to get the summary status from each PDP - boolean changeSeen = false; - for (OnapPDP pdp : pdps) { - // Check for shutdown - if (this.isRunning() == false) { - LOGGER.info("isRunning is false, getting out of loop."); - break; - } - // the id of the PDP is its url (though we add a query parameter) - URL pdpURL = idToURLMap.get(pdp.getId()); - if (pdpURL == null) { - // haven't seen this PDP before - String fullURLString = null; - try { - // Check PDP ID - if (CheckPDP.validateID(pdp.getId())) { - fullURLString = pdp.getId() + "?type=hb"; - pdpURL = new URL(fullURLString); - idToURLMap.put(pdp.getId(), pdpURL); - } - } catch (MalformedURLException e) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", - " PDP id '" + fullURLString + "' is not a valid URL"); - continue; - } - } - // Do a GET with type HeartBeat - String newStatus = ""; - HttpURLConnection connection = null; - try { - // Open up the connection - if (pdpURL != null) { - connection = (HttpURLConnection) pdpURL.openConnection(); - // Setup our method and headers - connection.setRequestMethod("GET"); - connection.setConnectTimeout(heartbeatTimeout); - // Authentication - String encoding = CheckPDP.getEncoding(pdp.getId()); - if (encoding != null) { - connection.setRequestProperty("Authorization", "Basic " + encoding); - } - // Do the connect - connection.connect(); - if (connection.getResponseCode() == 204) { - newStatus = connection.getHeaderField(XACMLRestProperties.PROP_PDP_HTTP_HEADER_HB); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Heartbeat '" + pdp.getId() + "' status='" + newStatus + "'"); - } - } else { - // anything else is an unexpected result - newStatus = PDPStatus.Status.UNKNOWN.toString(); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + - " Heartbeat connect response code " + connection.getResponseCode() + ": " + - pdp.getId()); - } - } - } catch (UnknownHostException e) { - newStatus = PDPStatus.Status.NO_SUCH_HOST.toString(); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Heartbeat '" + pdp.getId() + "' NO_SUCH_HOST"); - } catch (SocketTimeoutException e) { - newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Heartbeat '" + pdp.getId() + "' connection timeout"); - } catch (ConnectException e) { - newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Heartbeat '" + pdp.getId() + "' cannot connect"); - } catch (Exception e) { - newStatus = PDPStatus.Status.UNKNOWN.toString(); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - "Heartbeat '" + pdp.getId() + "' connect exception"); - } finally { - // cleanup the connection - if (connection != null) - connection.disconnect(); - } - if (!pdp.getStatus().getStatus().toString().equals(newStatus)) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("previous status='" + pdp.getStatus().getStatus() + "' new Status='" + - newStatus + "'"); - } - try { - setPDPSummaryStatus(pdp, newStatus); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - "Unable to set state for PDP '" + pdp.getId()); - } - changeSeen = true; - } - } - // Check for shutdown - if (this.isRunning() == false) { - LOGGER.info("isRunning is false, getting out of loop."); - break; - } - // if any of the PDPs changed state, tell the ACs to update - if (changeSeen) { - notifyAC(); - } - } - } catch (InterruptedException e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat interrupted. Shutting down"); - this.terminate(); - Thread.currentThread().interrupt(); - } - } - } - - /* - * HELPER to change Group status when PDP status is changed - * (Must NOT be called from a method that is synchronized on the papEngine or it may deadlock) - */ - private void setPDPSummaryStatus(OnapPDP pdp, PDPStatus.Status newStatus) throws PAPException { - setPDPSummaryStatus(pdp, newStatus.toString()); - } - - private void setPDPSummaryStatus(OnapPDP pdp, String newStatus) throws PAPException { - synchronized (papEngine) { - StdPDPStatus status = new StdPDPStatus(); - status.setStatus(PDPStatus.Status.valueOf(newStatus)); - ((StdPDP) pdp).setStatus(status); - // now adjust the group - StdPDPGroup group = (StdPDPGroup) papEngine.getPDPGroup((OnapPDP) pdp); - // if the PDP was just deleted it may transiently exist but not be in a group - if (group != null) { - group.resetStatus(); - } - } - } - - /* - * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine - * in the PDP group directories - */ - @Override - public void changed() { - // all PDPs in all groups need to be updated/sync'd - Set groups; - try { - groups = papEngine.getOnapPDPGroups(); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed"); - throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e); - } - for (OnapPDPGroup group : groups) { - groupChanged(group); - } - } - - public void changed(ONAPLoggingContext loggingContext) { - // all PDPs in all groups need to be updated/sync'd - Set groups; - try { - groups = papEngine.getOnapPDPGroups(); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed"); - throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e); - } - for (OnapPDPGroup group : groups) { - groupChanged(group, loggingContext); - } - } - - @Override - public void groupChanged(OnapPDPGroup group) { - // all PDPs within one group need to be updated/sync'd - for (OnapPDP pdp : group.getOnapPdps()) { - pdpChanged(pdp); - } - } - - public void groupChanged(OnapPDPGroup group, ONAPLoggingContext loggingContext) { - // all PDPs within one group need to be updated/sync'd - for (OnapPDP pdp : group.getOnapPdps()) { - pdpChanged(pdp, loggingContext); - } - } - - @Override - public void pdpChanged(OnapPDP pdp) { - // kick off a thread to do an event notification for each PDP. - // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc) - // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or - // time-out. - Thread t = new Thread(new UpdatePDPThread(pdp)); + private void pdpChanged(OnapPDP pdp, List pdpDataByGroup) { + Thread t = new Thread(new UpdatePdpThread(pdp, pdpDataByGroup)); if (CheckPDP.validateID(pdp.getId())) { t.start(); } } - public void pdpChanged(OnapPDP pdp, ONAPLoggingContext loggingContext) { - // kick off a thread to do an event notification for each PDP. - // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc) - // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or - // time-out. - Thread t = new Thread(new UpdatePDPThread(pdp, loggingContext)); + private void pdpChanged(OnapPDP pdp, OnapLoggingContext loggingContext, List pdpDataByGroup) { + Thread t = new Thread(new UpdatePdpThread(pdp, loggingContext, pdpDataByGroup)); if (CheckPDP.validateID(pdp.getId())) { t.start(); } } - private class UpdatePDPThread implements Runnable { - private OnapPDP pdp; - private String requestId; - private ONAPLoggingContext loggingContext; - - public UpdatePDPThread(OnapPDP pdp) { - this.pdp = pdp; - } - - public UpdatePDPThread(OnapPDP pdp, ONAPLoggingContext loggingContext) { - this.pdp = pdp; - if ((loggingContext != null) && (loggingContext.getRequestID() != null || - Objects.equals(loggingContext.getRequestID(), ""))) { - this.requestId = loggingContext.getRequestID(); - } - this.loggingContext = loggingContext; - } - - public void run() { - // send the current configuration to one PDP - HttpURLConnection connection = null; - // get a new logging context for the thread - try { - if (this.loggingContext == null) { - loggingContext = new ONAPLoggingContext(baseLoggingContext); - } - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Failed to send property file to " + pdp.getId()); - // Since this is a server-side error, it probably does not reflect a problem on the client, - // so do not change the PDP status. - return; - } - try { - loggingContext.setServiceName("PAP:PDP.putConfig"); - // If a requestId was provided, use it, otherwise generate one; post to loggingContext to be used - // later when calling PDP - if ((requestId == null) || (Objects.equals(requestId, ""))) { - UUID requestID = UUID.randomUUID(); - loggingContext.setRequestID(requestID.toString()); - PolicyLogger - .info("requestID not provided in call to XACMLPapSrvlet (UpdatePDPThread) so we generated" + - " one: " + - loggingContext.getRequestID()); - } else { - loggingContext.setRequestID(requestId); - PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (UpdatePDPThread): " + - loggingContext.getRequestID()); - } - loggingContext.transactionStarted(); - // the Id of the PDP is its URL - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("creating url for id '" + pdp.getId() + "'"); - } - //TODO - currently always send both policies and pips. Do we care enough to add code to allow - // sending just one or the other? - //TODO (need to change "cache=", implying getting some input saying which to change) - URL url = new URL(pdp.getId() + "?cache=all"); - // Open up the connection - connection = (HttpURLConnection) url.openConnection(); - // Setup our method and headers - connection.setRequestMethod("PUT"); - // Authentication - String encoding = CheckPDP.getEncoding(pdp.getId()); - if (encoding != null) { - connection.setRequestProperty("Authorization", "Basic " + encoding); - } - connection.setRequestProperty("Content-Type", "text/x-java-properties"); - connection.setRequestProperty("X-ECOMP-RequestID", loggingContext.getRequestID()); - connection.setInstanceFollowRedirects(true); - connection.setDoOutput(true); - try (OutputStream os = connection.getOutputStream()) { - OnapPDPGroup group = papEngine.getPDPGroup((OnapPDP) pdp); - // if the PDP was just deleted, there is no group, but we want to send an update anyway - if (group == null) { - // create blank properties files - Properties policyProperties = new Properties(); - policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, ""); - policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); - policyProperties.store(os, ""); - Properties pipProps = new Properties(); - pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, ""); - pipProps.store(os, ""); - } else { - // send properties from the current group - group.getPolicyProperties().store(os, ""); - Properties policyLocations = new Properties(); - for (PDPPolicy policy : group.getPolicies()) { - policyLocations - .put(policy.getId() + ".url", XACMLPapServlet.papURL + "?id=" + policy.getId()); - } - policyLocations.store(os, ""); - group.getPipConfigProperties().store(os, ""); - } - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Failed to send property file to " + pdp.getId()); - // Since this is a server-side error, it probably does not reflect a problem on the client, - // so do not change the PDP status. - return; - } - // Do the connect - loggingContext.metricStarted(); - connection.connect(); - loggingContext.metricEnded(); - PolicyLogger.metrics("XACMLPapServlet UpdatePDPThread connection connect"); - if (connection.getResponseCode() == 204) { - LOGGER.info("Success. We are configured correctly."); - loggingContext.transactionEnded(); - auditLogger.info("Success. PDP is configured correctly."); - PolicyLogger.audit("Transaction Success. PDP is configured correctly."); - setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE); - } else if (connection.getResponseCode() == 200) { - LOGGER.info("Success. PDP needs to update its configuration."); - loggingContext.transactionEnded(); - auditLogger.info("Success. PDP needs to update its configuration."); - PolicyLogger.audit("Transaction Success. PDP is configured correctly."); - setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH); - } else { - LOGGER.warn("Failed: " + connection.getResponseCode() + " message: " + - connection.getResponseMessage()); - loggingContext.transactionEnded(); - auditLogger.warn("Failed: " + connection.getResponseCode() + " message: " + - connection.getResponseMessage()); - PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + " message: " + - connection.getResponseMessage()); - setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN); - } - } catch (Exception e) { - LOGGER.debug(e); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Unable to sync config with PDP '" + pdp.getId() + "'"); - loggingContext.transactionEnded(); - PolicyLogger.audit("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e); - try { - setPDPSummaryStatus(pdp, PDPStatus.Status.UNKNOWN); - } catch (PAPException e1) { - LOGGER.debug(e1); - PolicyLogger - .audit("Transaction Failed: Unable to set status of PDP " + pdp.getId() + " to UNKNOWN: " + - e); - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Unable to set status of PDP '" + pdp.getId() + "' to UNKNOWN"); - } - } finally { - // cleanup the connection - if (connection != null) { - connection.disconnect(); - } - // tell the AC to update it's status info - notifyAC(); - } - } + private List getPdpDataByGroup(OnapPDPGroup group) { + DataToNotifyPdp dataToNotify = new DataToNotifyPdp(); + return dataToNotify.setPolicyConfigProperties(group); } - /* - * RESTful Interface from PAP to ACs notifying them of changes - */ - private void notifyAC() { - // kick off a thread to do one event notification for all registered ACs - // This needs to be on a separate thread so that ACs can make calls back to PAP to get the updated Group data - // as part of processing this message on their end. - Thread t = new Thread(new NotifyACThread()); - t.start(); - } - - private class NotifyACThread implements Runnable { - public void run() { - List disconnectedACs = new ArrayList<>(); - // There should be no Concurrent exception here because the list is a CopyOnWriteArrayList. - // The "for each" loop uses the collection's iterator under the covers, so it should be correct. - for (String acURL : adminConsoleURLStringList) { - HttpURLConnection connection = null; - try { - acURL += "?PAPNotification=true"; - //TODO - Currently we just tell AC that "Something changed" without being specific. Do we want - // to tell it which group/pdp changed? - //TODO - If so, put correct parameters into the Query string here - acURL += "&objectType=all" + "&action=update"; - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("creating url for id '" + acURL + "'"); - } - //TODO - currently always send both policies and pips. Do we care enough to add code to allow - // sending just one or the other? - //TODO (need to change "cache=", implying getting some input saying which to change) - URL url = new URL(acURL); - // Open up the connection - connection = (HttpURLConnection) url.openConnection(); - // Setup our method and headers - connection.setRequestMethod("PUT"); - connection.setRequestProperty("Content-Type", "text/x-java-properties"); - // 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. - //TODO - is this needed for a PUT? seems better to leave in for now? - connection.setInstanceFollowRedirects(false); - // Do not include any data in the PUT because this is just a - // notification to the AC. - // The AC will use GETs back to the PAP to get what it needs - // to fill in the screens. - // Do the connect - connection.connect(); - if (connection.getResponseCode() == 204) { - LOGGER.info("Success. We updated correctly."); - } else { - LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Failed: " + connection.getResponseCode() + - " message: " + connection.getResponseMessage()); - } - - } catch (Exception e) { - PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", - " Unable to sync config AC '" + acURL + "'"); - disconnectedACs.add(acURL); - } finally { - // cleanup the connection - if (connection != null) - connection.disconnect(); - } - } - // remove any ACs that are no longer connected - if (!disconnectedACs.isEmpty()) { - adminConsoleURLStringList.removeAll(disconnectedACs); - } - } + private List getPdpDataByPdpId(OnapPDP pdp) { + DataToNotifyPdp dataToNotify = new DataToNotifyPdp(); + return dataToNotify.setPolicyConfigProperties(pdp, papEngine); } - private void testService(ONAPLoggingContext loggingContext, HttpServletResponse response) throws IOException { + private void testService(OnapLoggingContext loggingContext, HttpServletResponse response) throws IOException { LOGGER.info("Test request received"); try { im.evaluateSanity(); - //If we make it this far, all is well + // If we make it this far, all is well String message = "GET:/pap/test called and PAP " + papResourceName + " is OK"; LOGGER.info(message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); response.setStatus(HttpServletResponse.SC_OK); + return; } catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException e) { String submsg; if (e instanceof ForwardProgressException) { @@ -2956,26 +1581,28 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList submsg = " Standby Status is NOT PROVIDING SERVICE."; } - String message = "GET:/pap/test called and PAP " + papResourceName + submsg - + " Exception Message: " + e.getMessage(); + String message = + "GET:/pap/test called and PAP " + papResourceName + submsg + " Exception Message: " + e.getMessage(); LOGGER.info(message, e); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; } catch (Exception e) { - //A subsystem is not making progress, is locked, standby or is not responding + // A subsystem is not making progress, is locked, standby or is not + // responding String eMsg = e.getMessage(); if (eMsg == null) { eMsg = "No Exception Message"; } String message = "GET:/pap/test called and PAP " + papResourceName + " has had a subsystem failure." - + " Exception Message: " + eMsg; + + " Exception Message: " + eMsg; LOGGER.info(message, e); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); - //Get the specific list of subsystems that failed + // Get the specific list of subsystems that failed String ssFailureList = null; for (String failedSS : papDependencyGroupsFlatArray) { if (eMsg.contains(failedSS)) { @@ -2991,6 +1618,20 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } response.addHeader("X-ONAP-SubsystemFailure", ssFailureList); setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); + return; + } + } + + private void setLoggingContext(OnapLoggingContext loggingContext, String methodType, String serviceName) { + loggingContext.transactionStarted(); + loggingContext.setServiceName(serviceName); + if (loggingContext.getRequestId() == null || "".equals(loggingContext.getRequestId())) { + UUID requestID = UUID.randomUUID(); + loggingContext.setRequestId(requestID.toString()); + PolicyLogger + .info("requestID not provided in call to XACMLPapServlet ('" + methodType + "') so we generated one"); + } else { + PolicyLogger.info("requestID was provided in call to XACMLPapServlet ('" + methodType + "')"); } } @@ -3000,21 +1641,17 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList private boolean authorizeRequest(HttpServletRequest request) { String clientCredentials = request.getHeader(ENVIRONMENT_HEADER); // Check if the Client is Authorized. - if (clientCredentials != null && clientCredentials.equalsIgnoreCase(environment)) { - return true; - } else { - return false; - } + return clientCredentials != null && clientCredentials.equalsIgnoreCase(environment); } private static void loadWebapps() throws PAPException { if (actionHome == null || configHome == null) { - Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS)); - //Sanity Check + Path webappsPath = Paths.get(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_WEBAPPS)); + // Sanity Check if (webappsPath == null) { - PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS); + PolicyLogger.error("Invalid Webapps Path Location property : " + XacmlRestProperties.PROP_PAP_WEBAPPS); throw new PAPException( - "Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS); + "Invalid Webapps Path Location property : " + XacmlRestProperties.PROP_PAP_WEBAPPS); } Path webappsPathConfig = Paths.get(webappsPath.toString() + File.separator + "Config"); Path webappsPathAction = Paths.get(webappsPath.toString() + File.separator + "Action"); @@ -3023,8 +1660,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList Files.createDirectories(webappsPathConfig); } catch (IOException e) { PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", - "Failed to create config directory: " - + webappsPathConfig.toAbsolutePath().toString()); + "Failed to create config directory: " + webappsPathConfig.toAbsolutePath().toString()); } } if (Files.notExists(webappsPathAction)) { @@ -3032,7 +1668,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList Files.createDirectories(webappsPathAction); } catch (IOException e) { LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Failed to create action directory: " - + webappsPathAction.toAbsolutePath().toString(), e); + + webappsPathAction.toAbsolutePath().toString(), e); } } actionHome = webappsPathAction.toString(); @@ -3068,10 +1704,6 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList actionHome = getActionHome(); } - public static EntityManagerFactory getEmf() { - return emf; - } - public IntegrityAudit getIa() { return ia; } @@ -3088,8 +1720,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return papEngine; } - public static PolicyDBDaoTransaction getDbDaoTransaction() { - return policyDBDao.getNewTransaction(); + public static PolicyDbDaoTransaction getDbDaoTransaction() { + return policyDbDao.getNewTransaction(); } public static String getPapDbDriver() { @@ -3117,11 +1749,11 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } public static String getPapDbPassword() { - return papDbPassword; + return papDbPd; } public static void setPapDbPassword(String papDbPassword) { - XACMLPapServlet.papDbPassword = papDbPassword; + XACMLPapServlet.papDbPd = papDbPassword; } public static String getMsOnapName() { @@ -3139,4 +1771,12 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList public static void setMsPolicyName(String msPolicyName) { XACMLPapServlet.msPolicyName = msPolicyName; } -} \ No newline at end of file + + public OnapLoggingContext getBaseLoggingContext() { + return baseLoggingContext; + } + + public void setBaseLoggingContext(OnapLoggingContext baseLoggingContext) { + this.baseLoggingContext = baseLoggingContext; + } +}