diff options
author | pa834y <pa834y@att.com> | 2019-03-11 10:34:22 -0400 |
---|---|---|
committer | pa834y <pa834y@att.com> | 2019-03-20 15:30:20 -0400 |
commit | 2903daf20f5e473a96a36342151a26e9f2e55005 (patch) | |
tree | e6da180b8eda43c4f20c05121e265b403fdb1b4a /ONAP-PAP-REST/src/main | |
parent | d71b3cf8a983a95fced20eed0cb09aea84aa1b3c (diff) |
use hibernate and breakup dbdao and papservlet
Change-Id: Ifa655d56bda0ab4c748f188767122e7bd927155b
Issue-ID: POLICY-1417
Signed-off-by: pa834y <pa834y@att.com>
Diffstat (limited to 'ONAP-PAP-REST/src/main')
19 files changed, 4707 insertions, 4187 deletions
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/ConsoleAndApiService.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/ConsoleAndApiService.java new file mode 100644 index 000000000..a9ef7eee6 --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/ConsoleAndApiService.java @@ -0,0 +1,956 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest; + +import com.att.research.xacml.api.pap.PAPException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Scanner; +import java.util.Set; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.onap.policy.common.logging.ONAPLoggingContext; +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.handler.PushPolicyHandler; +import org.onap.policy.xacml.api.XACMLErrorConstants; +import org.onap.policy.xacml.api.pap.OnapPDP; +import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.onap.policy.xacml.api.pap.PAPPolicyEngine; +import org.onap.policy.xacml.std.pap.StdPDP; +import org.onap.policy.xacml.std.pap.StdPDPGroup; +import org.onap.policy.xacml.std.pap.StdPDPPolicy; + +public class ConsoleAndApiService { + + private static final Logger LOGGER = FlexLogger.getLogger(ConsoleAndApiService.class); + private static final Logger auditLogger = FlexLogger.getLogger("auditLogger"); + private static final String ADD_GROUP_ERROR = "addGroupError"; + private static final String REGEX = "[0-9a-zA-Z._, ]*"; + private static final String TRANSACTIONFAILED = "Transaction Failed - See Error.log"; + private static final String PAPSERVLETDOACPOST = "XACMLPapServlet.doACPost"; + private static final String ACPOSTCOMMITTRANS = "XACMLPapServlet doACPost commitTransaction"; + private static final String XACMLPAPSERVLET = "XACMLPapServlet"; + private static final String SUCCESS = "Success"; + private static final String ERROR = "error"; + private static final String MESSAGE = "message"; + private static final String POLICYID = "policyId"; + private static final String TRANSENDED = "Transaction Ended Successfully"; + + /** + * Requests from the Admin Console for operations not on single specific objects. + * + * @param request Servlet request + * @param response Servlet response + * @param groupId the group id + * @param loggingContext the logging context + * @param papEngine the pap engine + * @throws ServletException the servlet exception + * @throws IOException Signals that an I/O exception has occurred. + */ + public void doAcPost(HttpServletRequest request, HttpServletResponse response, String groupId, + ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException { + PolicyDBDaoTransaction doAcPostTransaction = null; + try { + String groupName = request.getParameter("groupName"); + String groupDescription = request.getParameter("groupDescription"); + String apiflag = request.getParameter("apiflag"); + String userId = request.getParameter("userId"); + if (groupName != null && groupDescription != null) { + // Args: group=<groupId> groupName=<name> + // groupDescription=<description> <= 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 = XACMLPapServlet.policyDBDao.getNewTransaction(); + try { + newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName, + unescapedDescription, PAPSERVLETDOACPOST); + papEngine.newGroup(unescapedName, unescapedDescription); + loggingContext.metricStarted(); + newGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics(ACPOSTCOMMITTRANS); + } catch (Exception e) { + newGroupTransaction.rollbackTransaction(); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, + " Unable to create new group"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + 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"); + } + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + 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(TRANSACTIONFAILED); + 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; + } + + // If the request contains a policyId then we know we are pushing + // the policy to PDP + if (request.getParameter(POLICYID) != null) { + String policyName = request.getParameter(POLICYID); + List<String> policyIdList = Arrays.asList(policyName.split(",")); + + loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy"); + LOGGER.info("PushPolicy Request - " + policyName + ", UserId - " + userId); + + StdPDPGroup updatedGroup = null; + StdPDPPolicy policyForSafetyCheck = new StdPDPPolicy(); + for (String policyId : policyIdList) { + PolicyDBDaoTransaction addPolicyToGroupTransaction = + XACMLPapServlet.policyDBDao.getNewTransaction(); + 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, + PAPSERVLETDOACPOST, userId); + loggingContext.metricStarted(); + addPolicyToGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics(ACPOSTCOMMITTRANS); + LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed"); + + if (policyId.contains("Config_MS_") || policyId.contains("BRMS_Param")) { + PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance(); + policyForSafetyCheck.setId(policyId); + if (pushPolicyHandler.preSafetyCheck(policyForSafetyCheck, XACMLPapServlet.getConfigHome())) { + LOGGER.debug("Precheck Successful."); + } + } + + // delete temporary policy file from the bin directory + Files.deleteIfExists(Paths.get(policyId)); + + } catch (Exception e) { + addPolicyToGroupTransaction.rollbackTransaction(); + String message = "Policy '" + policyName + "' 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(TRANSACTIONFAILED); + 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; + } + } + + /* + * 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. + */ + + // Get new transaction to perform updateGroup() + PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.policyDBDao.getNewTransaction(); + try { + // Assume that this is an update of an existing PDP + // Group + loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup"); + try { + acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut", userId); + } 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()); + } + + 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"); + // Group changed to send notification to PDPs, which + // might include changing the policies + getPapInstance().groupChanged(updatedGroup, loggingContext); + loggingContext.transactionEnded(); + LOGGER.info(SUCCESS); + } catch (Exception e) { + acPutTransaction.rollbackTransaction(); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " API PUT exception"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + 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, policyName); + response.addHeader("groupId", groupId); + + LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'"); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + LOGGER.info(TRANSENDED); + + return; + } else if (request.getParameter("default") != null) { + // Args: group=<groupId> 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 = XACMLPapServlet.policyDBDao.getNewTransaction(); + try { + setDefaultGroupTransaction.changeDefaultGroup(group, PAPSERVLETDOACPOST); + papEngine.setDefaultGroup(group); + loggingContext.metricStarted(); + setDefaultGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics(ACPOSTCOMMITTRANS); + } catch (Exception e) { + setDefaultGroupTransaction.rollbackTransaction(); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " Unable to set group"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + 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"); + } + auditLogger.info(SUCCESS); + LOGGER.info(TRANSENDED); + return; + } else if (request.getParameter("pdpId") != null) { + doAcPostTransaction = XACMLPapServlet.policyDBDao.getNewTransaction(); + // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group + loggingContext.setServiceName("AC:PAP.movePDP"); + String pdpId = request.getParameter("pdpId"); + OnapPDP pdp = papEngine.getPDP(pdpId); + OnapPDPGroup originalGroup = papEngine.getPDPGroup(pdp); + try { + doAcPostTransaction.movePdp(pdp, group, PAPSERVLETDOACPOST); + } 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(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(); + // Need to notify the PDP that it's config may have changed + getPapInstance().pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); + doAcPostTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics(ACPOSTCOMMITTRANS); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC POST exception"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + /** + * Requests from the Admin Console to GET info about the Groups and PDPs. + * + * @param request the request + * @param response the response + * @param groupId the group id + * @param loggingContext the logging context + * @param papEngine the pap engine + * @throws IOException Signals that an I/O exception has occurred. + */ + public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId, + ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) 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(TRANSENDED); + 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(TRANSENDED); + 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(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(TRANSENDED); + return; + } + } else { + // request is for top-level properties about all groups + loggingContext.setServiceName("AC:PAP.getAllGroups"); + Set<OnapPDPGroup> groups = null; + try { + groups = papEngine.getOnapPDPGroups(); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + 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(TRANSENDED); + 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(TRANSACTIONFAILED); + 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(TRANSACTIONFAILED); + 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(TRANSENDED); + 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=<groupId>) + // A Policy (groupId=<groupId> policyId=<policyId>) + // A PDP (groupId=<groupId> pdpId=<pdpId>) + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED "); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + 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(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + /** + * Requests from the Admin Console to create new items or update existing ones. + * + * @param request the request + * @param response the response + * @param groupId the group id + * @param loggingContext the logging context + * @param papEngine the pap engine + * @throws IOException Signals that an I/O exception has occurred. + */ + public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId, + ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException { + PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.policyDBDao.getNewTransaction(); + try { + String userId = request.getParameter("userId"); + // 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(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message); + return; + } + if (request.getParameter("policy") != null) { + // group=<groupId> policy=<policyId> 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(TRANSACTIONFAILED); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } else if (request.getParameter("pdpId") != null) { + // ARGS: group=<groupId> pdpId=<pdpId/URL> <= 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(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Bad input pdpid for object:" + objectFromJson); + } + StdPDP pdp = (StdPDP) objectFromJson; + if (pdp != null) { + OnapPDP origPdp = null; + try { + origPdp = papEngine.getPDP(pdpId); + } catch (PAPException e) { + LOGGER.error(e); + } + if (origPdp == 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"); + papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort()); + } 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()); + } + } else { + // this is a request to update the pdp + try { + acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut"); + papEngine.updatePDP(pdp); + } 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()); + } + } + 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(); + // this might affect the PDP, so notify it of the change + getPapInstance().pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); + acPutTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } 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=<groupId> pipId=<pipEngineId> 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(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else { + // Assume that this is an update of an existing PDP Group + // ARGS: group=<groupId> <= 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(TRANSACTIONFAILED); + 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", userId); + } else { + acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doACPut", userId); + } + } 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, XACMLPapServlet.getConfigHome())) { + 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"); + // Group changed, which might include changing the policies + getPapInstance().groupChanged(group, loggingContext); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } + } catch (PAPException e) { + LOGGER.debug(e); + acPutTransaction.rollbackTransaction(); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC PUT exception"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + /** + * Requests from the Admin Console to delete/remove items. + * + * @param request the request + * @param response the response + * @param groupId the group id + * @param loggingContext the logging context + * @param papEngine the pap engine + * @throws IOException Signals that an I/O exception has occurred. + */ + public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId, + ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException { + PolicyDBDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.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(TRANSACTIONFAILED); + 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=<groupId> policy=<policyId> [delete=<true|false>] <= + // delete policy file from group + loggingContext.setServiceName("AC:PAP.deletePolicy"); + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else if (request.getParameter("pdpId") != null) { + // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP + String pdpId = request.getParameter("pdpId"); + OnapPDP pdp = papEngine.getPDP(pdpId); + removePdpFromGroup(removePdpOrGroupTransaction, pdp, papEngine); + // adjust the status of the group, which may have changed when + // we removed this PDP + ((StdPDPGroup) group).resetStatus(); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + // update the PDP and tell it that it has NO Policies (which + // prevents it from serving PEP Requests) + getPapInstance().pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); + removePdpOrGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } else if (request.getParameter("pipId") != null) { + // group=<groupId> pipId=<pipEngineId> <= delete PIP config for + // given engine + loggingContext.setServiceName("AC:PAP.deletePIPConfig"); + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED"); + return; + } else { + // ARGS: group=<groupId> movePDPsToGroupId=<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<OnapPDP> movedPdps = new HashSet<>(); + movedPdps.addAll(group.getOnapPdps()); + // do the move/remove + deleteGroup(removePdpOrGroupTransaction, group, moveToGroup, papEngine); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + // notify any PDPs in the removed set that their config may have + // changed + for (OnapPDP pdp : movedPdps) { + getPapInstance().pdpChanged(pdp, loggingContext); + } + loggingContext.metricStarted(); + removePdpOrGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); + loggingContext.transactionEnded(); + auditLogger.info(SUCCESS); + PolicyLogger.audit(TRANSENDED); + return; + } + } catch (PAPException e) { + removePdpOrGroupTransaction.rollbackTransaction(); + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC DELETE exception"); + loggingContext.transactionEnded(); + PolicyLogger.audit(TRANSACTIONFAILED); + setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return; + } + } + + private void deleteGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group, + OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException { + try { + removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete"); + papEngine.removeGroup(group, moveToGroup); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, XACMLPAPSERVLET, + " Failed to delete PDP Group. Exception"); + throw new PAPException(e.getMessage()); + } + } + + private void removePdpFromGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp, + PAPPolicyEngine papEngine) throws PAPException { + try { + removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete"); + papEngine.removePDP(pdp); + } catch (Exception e) { + throw new PAPException(e); + } + } + + private XACMLPapServlet getPapInstance() { + return new XACMLPapServlet(); + } + + private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) { + try { + mapper.writeValue(response.getOutputStream(), value); + } catch (Exception e) { + LOGGER.error(e); + } + } + + private void setResponseError(HttpServletResponse response, int responseCode, String message) { + try { + if (message != null && !message.isEmpty()) { + response.sendError(responseCode, message); + } + } catch (IOException e) { + LOGGER.error("Error setting Error response Header ", e); + } + return; + } +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DataToNotifyPdp.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DataToNotifyPdp.java new file mode 100644 index 000000000..825aeb774 --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DataToNotifyPdp.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.util.XACMLProperties; +import com.google.common.base.Joiner; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; +import java.util.TreeSet; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.rest.dao.CommonClassDao; +import org.onap.policy.rest.jpa.GroupEntity; +import org.onap.policy.rest.jpa.PolicyEntity; +import org.onap.policy.xacml.api.pap.OnapPDP; +import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.onap.policy.xacml.api.pap.PAPPolicyEngine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class DataToNotifyPdp { + + private static final Logger LOGGER = FlexLogger.getLogger(DataToNotifyPdp.class); + private static CommonClassDao commonClassDao; + private Properties policyLocations = null; + private static Properties pipProperties = null; + + @Autowired + public DataToNotifyPdp(CommonClassDao commonClassDao) { + DataToNotifyPdp.commonClassDao = commonClassDao; + } + + public DataToNotifyPdp() { + // default constructor. + } + + + private static Properties readPipProperties() throws IOException { + if (pipProperties == null) { + try (FileInputStream inputStream = new FileInputStream(Paths.get("pip.properties").toString())) { + pipProperties = new Properties(); + pipProperties.load(inputStream); + } + } + return pipProperties; + } + + /** + * Sets the policy config properties. + * + * @param pdp the pdp + * @param papEngine the pap engine + * @return the list + */ + public List<Properties> setPolicyConfigProperties(OnapPDP pdp, PAPPolicyEngine papEngine) { + OnapPDPGroup group = null; + try { + group = papEngine.getPDPGroup(pdp); + } catch (PAPException e) { + LOGGER.error("Pdp Id not found in PDP Groups.", e); + } + return setPolicyConfigProperties(group); + } + + /** + * This method is used to set the policyGroupEntity data to properties. So, we can update the + * pdp thread with the latest policy info. Hence, considering Database as master instead of File + * System. To overcome the redundancy issues. + * + * @param group Input is OnapPDP Group name. + */ + public List<Properties> setPolicyConfigProperties(OnapPDPGroup group) { + boolean groupCheck = false; + List<Properties> properties = new ArrayList<>(); + policyLocations = new Properties(); + Properties policyProperties = new Properties(); + Properties pipProps = new Properties(); + if (group != null && group.getName() != null) { + GroupEntity data = + (GroupEntity) commonClassDao.getEntityItem(GroupEntity.class, "groupName", group.getName()); + if (data != null) { + policyProperties = setPolicyProperties(data); + try { + pipProps = readPipProperties(); + } catch (IOException e) { + LOGGER.error("Error Occured while reading the pip properties.", e); + } + groupCheck = true; + } else { + LOGGER.info("Group Name exists, but not exists in DB. So, adding the empty properties list."); + setEmptyPolicyProperties(policyProperties, pipProps); + } + } else { + LOGGER.info("Group Name is null. So, adding the empty properties list."); + setEmptyPolicyProperties(policyProperties, pipProps); + } + properties.add(policyProperties); + properties.add(pipProps); + if (groupCheck) { + properties.add(policyLocations); + } + return properties; + } + + /** + * Based on the Group Entity list, write the policyNames to properties. + * + * @param data group entity object. + * @return properties. + */ + private Properties setPolicyProperties(GroupEntity data) { + GroupEntity entity = data; + Properties policyProperties = new Properties() { + private static final long serialVersionUID = 1L; + + // For Debugging it is helpful for the file to be in a sorted order, + // any by returning the keys in the natural Alpha order for strings we get close enough. + // TreeSet is sorted, and this just overrides the normal Properties method to get the + // keys. + @Override + public synchronized Enumeration<Object> keys() { + return Collections.enumeration(new TreeSet<Object>(super.keySet())); + } + }; + List<String> roots = new ArrayList<>(); + for (PolicyEntity policy : entity.getPolicies()) { + // for all policies need to tell PDP the "name", which is the base name for the file id + String policyName = policy.getScope() + "." + policy.getPolicyName(); + String policyNameWithNoScope = policy.getPolicyName(); + if (policyName != null) { + policyProperties.setProperty(policyName + ".name", policy.getScope() + "." + + policyNameWithNoScope.substring(0, policyNameWithNoScope.indexOf('.'))); + policyLocations.put(policyName + ".url", XACMLPapServlet.papURL + "?id=" + policyName); + } + roots.add(policyName); + } + policyProperties.setProperty(XACMLProperties.PROP_ROOTPOLICIES, Joiner.on(',').join(roots)); + policyProperties.setProperty(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + return policyProperties; + } + + /** + * When Group name is null, then we need to consider group is deleted and notify pdp with empty + * properties. + * + * @param policyProperties policyProperties input. + * @param pipProps pipProps input. + */ + private void setEmptyPolicyProperties(Properties policyProperties, Properties pipProps) { + // create blank properties files + policyProperties.put(XACMLProperties.PROP_ROOTPOLICIES, ""); + policyProperties.put(XACMLProperties.PROP_REFERENCEDPOLICIES, ""); + pipProps.setProperty(XACMLProperties.PROP_PIP_ENGINES, ""); + } + +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/Heartbeat.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/Heartbeat.java new file mode 100644 index 000000000..2687799cc --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/Heartbeat.java @@ -0,0 +1,244 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPStatus; +import com.att.research.xacml.util.XACMLProperties; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +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.restAuth.CheckPDP; +import org.onap.policy.rest.XACMLRestProperties; +import org.onap.policy.xacml.api.pap.OnapPDP; +import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.onap.policy.xacml.api.pap.PAPPolicyEngine; + + +/** + * 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. + */ +public class Heartbeat implements Runnable { + + private static final Logger LOGGER = FlexLogger.getLogger(Heartbeat.class); + + private PAPPolicyEngine papEngine; + private Set<OnapPDP> pdps = new HashSet<>(); + private int heartbeatInterval; + private int heartbeatTimeout; + private static final String HEARTBEATSTRING = " Heartbeat '"; + private static final String XACMLPAPSERVLET = "XacmlPapServlet"; + private static final String ISRUNNINGFALSE = "isRunning is false, getting out of loop."; + private volatile boolean isRunning = false; + + public synchronized boolean isHeartBeatRunning() { + return this.isRunning; + } + + public synchronized void terminate() { + this.isRunning = false; + } + + /** + * Instantiates a new heartbeat. + * + * @param papEngine2 the pap engine 2 + */ + 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; + } + try { + while (this.isHeartBeatRunning()) { + // Wait the given time + Thread.sleep(heartbeatInterval); + // get the list of PDPs (may have changed since last time) + pdps.clear(); + synchronized (papEngine) { + getPdpsFromGroup(); + } + // Check for shutdown + if (!this.isHeartBeatRunning()) { + LOGGER.info(ISRUNNINGFALSE); + break; + } + notifyEachPdp(); + // Check for shutdown + if (!this.isHeartBeatRunning()) { + LOGGER.info(ISRUNNINGFALSE); + break; + } + } + } catch (InterruptedException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " Heartbeat interrupted. Shutting down"); + this.terminate(); + Thread.currentThread().interrupt(); + } + } + + private void getPdpsFromGroup() { + 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"); + } + } + + private void notifyEachPdp() { + HashMap<String, URL> idToUrlMap = new HashMap<>(); + for (OnapPDP pdp : pdps) { + // Check for shutdown + if (!this.isHeartBeatRunning()) { + LOGGER.info(ISRUNNINGFALSE); + 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"); + } + } + updatePdpStatus(pdp, openPdpConnection(pdpUrl, pdp)); + } + } + + private String openPdpConnection(URL pdpUrl, OnapPDP pdp) { + // 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, + HEARTBEATSTRING + pdp.getId() + "' NO_SUCH_HOST"); + } catch (SocketTimeoutException e) { + newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET, + HEARTBEATSTRING + pdp.getId() + "' connection timeout"); + } catch (ConnectException e) { + newStatus = PDPStatus.Status.CANNOT_CONNECT.toString(); + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET, + HEARTBEATSTRING + pdp.getId() + "' cannot connect"); + } catch (Exception e) { + newStatus = PDPStatus.Status.UNKNOWN.toString(); + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, XACMLPAPSERVLET, + HEARTBEATSTRING + pdp.getId() + "' connect exception"); + } finally { + // cleanup the connection + if (connection != null) + connection.disconnect(); + } + return newStatus; + } + + private void updatePdpStatus(OnapPDP pdp, String newStatus) { + if (!pdp.getStatus().getStatus().toString().equals(newStatus)) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("previous status='" + pdp.getStatus().getStatus() + "' new Status='" + newStatus + "'"); + } + try { + getPAPInstance().setPDPSummaryStatus(pdp, newStatus); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, + "Unable to set state for PDP '" + pdp.getId()); + } + } + } + + private XACMLPapServlet getPAPInstance() { + return new XACMLPapServlet(); + } + +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/UpdatePdpThread.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/UpdatePdpThread.java new file mode 100644 index 000000000..11576d314 --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/UpdatePdpThread.java @@ -0,0 +1,204 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPStatus; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; +import java.util.Properties; +import java.util.UUID; +import org.onap.policy.common.logging.ONAPLoggingContext; +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.restAuth.CheckPDP; +import org.onap.policy.xacml.api.pap.OnapPDP; + +public class UpdatePdpThread implements Runnable { + + private static final Logger LOGGER = FlexLogger.getLogger(UpdatePdpThread.class); + private ONAPLoggingContext baseLoggingContext = new XACMLPapServlet().getBaseLoggingContext(); + private static final Logger auditLogger = FlexLogger.getLogger("auditLogger"); + private static final String XACMLPAPSERVLET = "XACMLPapServlet"; + private static final String MESSAGE = " message: "; + + private OnapPDP pdp; + private String requestId; + private ONAPLoggingContext loggingContext; + private List<Properties> properties; + + + public UpdatePdpThread(OnapPDP pdp, List<Properties> properties) { + this.pdp = pdp; + this.properties = properties; + } + + /** + * Instantiates a new update pdp thread. + * + * @param pdp the pdp + * @param loggingContext the logging context + * @param properties the properties + */ + public UpdatePdpThread(OnapPDP pdp, ONAPLoggingContext loggingContext, List<Properties> properties) { + this.pdp = pdp; + if (loggingContext != null + && (loggingContext.getRequestID() != null || "".equals(loggingContext.getRequestID()))) { + this.requestId = loggingContext.getRequestID(); + } + this.loggingContext = loggingContext; + this.properties = properties; + } + + @Override + 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 || "".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() + "'"); + } + 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); + if (!writePropertiesToStream(connection)) { + 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 - " + pdp.getId()); + loggingContext.transactionEnded(); + auditLogger.info("Success. PDP is configured correctly."); + PolicyLogger.audit("Transaction Success. PDP is configured correctly."); + getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.UP_TO_DATE); + } else if (connection.getResponseCode() == 200) { + LOGGER.info("Success. PDP needs to update its configuration - " + pdp.getId()); + loggingContext.transactionEnded(); + auditLogger.info("Success. PDP needs to update its configuration."); + PolicyLogger.audit("Transaction Success. PDP is configured correctly."); + getPapInstance().setPDPSummaryStatus(pdp, PDPStatus.Status.OUT_OF_SYNCH); + } else { + LOGGER.warn("Failed: " + connection.getResponseCode() + MESSAGE + connection.getResponseMessage() + + pdp.getId()); + loggingContext.transactionEnded(); + auditLogger.warn("Failed: " + connection.getResponseCode() + MESSAGE + connection.getResponseMessage()); + PolicyLogger.audit("Transaction Failed: " + connection.getResponseCode() + MESSAGE + + connection.getResponseMessage()); + getPapInstance().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); + LOGGER.info("Transaction Failed: Unable to sync config with PDP '" + pdp.getId() + "': " + e); + try { + getPapInstance().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(); + } + } + } + + private boolean writePropertiesToStream(HttpURLConnection connection) { + try (OutputStream os = connection.getOutputStream()) { + // Policy Properties + properties.get(0).store(os, ""); + // Pip Properties + properties.get(1).store(os, ""); + // Policy Locations + if (properties.size() == 3) { + properties.get(2).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 false; + } + return true; + } + + private XACMLPapServlet getPapInstance() { + return new XACMLPapServlet(); + } + +} 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..30d09edb5 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,7 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,34 +20,28 @@ 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.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; @@ -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; @@ -74,6 +67,7 @@ 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.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; @@ -96,31 +90,18 @@ 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 */ -@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.") - }) +@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.")}) 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 +112,25 @@ 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<String> 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; + public 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; + public static PolicyDBDao policyDBDao; /* * papEngine - This is our engine workhorse that manages the PDP Groups and Nodes. */ @@ -163,7 +142,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 +151,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; /* @@ -181,6 +160,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList */ private static transient Thread initiateThread = null; private transient ONAPLoggingContext baseLoggingContext = null; + private static final String GROUPID = "groupId"; /** * @see HttpServlet#HttpServlet() @@ -192,6 +172,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see Servlet#init(ServletConfig) */ + @Override public void init(ServletConfig config) throws ServletException { try { // Logging @@ -203,6 +184,7 @@ 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); // Load the properties @@ -223,13 +205,15 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList " ERROR: Bad papNodeType property entry"); throw new PAPException("papNodeType is null"); } - //Integer will throw an exception of anything is missing or unrecognized + // 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)); int papAuditTimeout = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); - //Boolean will default to false if anything is missing or unrecognized + // Boolean will default to false if anything is missing or + // unrecognized boolean papAuditFlag = Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG)); boolean papFileSystemAudit = @@ -239,7 +223,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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)); int failedCounterThreshold = @@ -248,41 +233,26 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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*************************************" + 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 @@ -294,49 +264,33 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // 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 + // 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 + // Create the policyDBDao setPolicyDBDao(); // Load our PAP engine, first create a factory ONAPPapEngineFactory factory = ONAPPapEngineFactory .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); + 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 + // 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); if (updatedGroup != null) { @@ -344,23 +298,23 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } 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))) { 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); @@ -370,6 +324,26 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList throw new ServletException( 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(); + } + } } private static void startInitiateThreadService(Thread thread) { @@ -393,7 +367,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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); } @@ -402,9 +376,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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); + 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"); } } @@ -419,9 +392,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); } @@ -448,8 +421,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList setActionHome(); 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); @@ -461,19 +434,19 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList setPapDbUrl(papDbUrl); 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 + papDbPd = CryptoUtils .decryptTxtNoExStr(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD, "")); - if (papDbPassword == null) { + if (papDbPd == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", " ERROR: Bad papDbPassword property entry"); throw new PAPException("papDbPassword is null"); } - setPapDbPassword(papDbPassword); + setPapDbPassword(papDbPd); papResourceName = XACMLProperties.getProperty(XACMLRestProperties.PAP_RESOURCE_NAME); if (papResourceName == null) { PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "XACMLPapServlet", @@ -481,24 +454,24 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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 + // 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. "); + 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 +481,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList /** * @see Servlet#destroy() - * <p> - * 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. + * <p> + * 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 +512,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)"); - } + setLoggingContext(loggingContext, "doPost", "PAP.post"); PolicyDBDaoTransaction pdpTransaction = null; - loggingContext.metricStarted(); 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; + + " 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"); @@ -577,8 +546,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); + + " 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"); @@ -586,31 +554,24 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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); - 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; } try { loggingContext.metricStarted(); 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 +583,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(); @@ -649,7 +610,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList "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) { + } 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 +644,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; @@ -698,7 +659,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList "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,13 +669,13 @@ 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, @@ -739,8 +700,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 +739,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 +752,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,36 +771,27 @@ 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)"); - } + setLoggingContext(loggingContext, "doGet", "PAP.get"); loggingContext.metricStarted(); 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(); @@ -852,8 +799,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); + + " state of " + im.getStateManager().getAdminState() + "\n Exception Message: " + ae.getMessage(); LOGGER.info(message, ae); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); @@ -861,24 +807,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); + 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); - 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; } // Request from the API to get the gitPath String apiflag = request.getParameter("apiflag"); @@ -909,12 +845,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 +874,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<OnapPDPGroup> groups = null; @@ -976,7 +911,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 +946,14 @@ 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,18 +976,11 @@ 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)"); - } + setLoggingContext(loggingContext, "doPut", "PAP.put"); try { loggingContext.metricStarted(); im.startTransaction(); @@ -1061,11 +989,9 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } 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(); + 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(); + message += " but it has a Standby Status of " + im.getStateManager().getStandbyStatus(); } else { message += " but an exception occurred"; @@ -1081,12 +1007,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 +1032,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); @@ -1160,11 +1091,11 @@ 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)) { @@ -1191,7 +1122,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,18 +1191,11 @@ 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)"); - } + setLoggingContext(loggingContext, "doDelete", "PAP.delete"); try { loggingContext.metricStarted(); im.startTransaction(); @@ -1279,8 +1203,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); + + " state of " + im.getStateManager().getAdminState() + "\n Exception Message: " + ae.getMessage(); LOGGER.info(message, ae); PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message); loggingContext.transactionEnded(); @@ -1288,30 +1211,20 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); + 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); - 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; } loggingContext.metricStarted(); 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? @@ -1342,7 +1255,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 +1266,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 +1278,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,16 +1288,19 @@ 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; @@ -1419,8 +1335,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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 +1353,13 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList * @throws IOException */ public void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId, - ONAPLoggingContext loggingContext) throws IOException { + 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 +1374,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<PDPPolicy> 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 +1390,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", null); } 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 +1412,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 +1420,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,1115 +1435,39 @@ 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); - } - } - - /** - * Requests from the Admin Console for operations not on single specific objects - * - * @param request - * @param response - * @param groupId - * @param loggingContext - * @throws ServletException - * @throws IOException - */ - 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=<groupId> groupName=<name> groupDescription=<description> <= 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; - } - - // If the request contains a policyId then we know we are pushing the policy to PDP - if (request.getParameter("policyId") != null) { - - 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"); - } - - 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"); - - } 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; - } - - 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. - */ - - // 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()); - } - - 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=<groupId> 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=<groupId> pdpId=<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<OnapPDPGroup> 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=<groupId>) - // A Policy (groupId=<groupId> policyId=<policyId>) - // A PDP (groupId=<groupId> pdpId=<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=<groupId> policy=<policyId> 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=<groupId> pdpId=<pdpId/URL> <= 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=<groupId> pipId=<pipEngineId> 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=<groupId> <= 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=<groupId> policy=<policyId> [delete=<true|false>] <= 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=<groupId> pdpId=<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=<groupId> pipId=<pipEngineId> <= 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=<groupId> movePDPsToGroupId=<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<OnapPDP> 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 - * <p> - * Heartbeat with all known PDPs. - * <p> - * Implementation note: - * <p> - * The PDPs are contacted Sequentially, not in Parallel. - * <p> - * 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. - * <p> - * 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<OnapPDP> 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<String, URL> 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(); - } + return; } } /* - * 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) + * 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 { + public void setPDPSummaryStatus(OnapPDP pdp, PDPStatus.Status newStatus) throws PAPException { setPDPSummaryStatus(pdp, newStatus.toString()); } - private void setPDPSummaryStatus(OnapPDP pdp, String newStatus) throws PAPException { + 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((OnapPDP) pdp); - // if the PDP was just deleted it may transiently exist but not be in a 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(); } @@ -2639,8 +1475,8 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } /* - * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine - * in the PDP group directories + * Callback methods telling this servlet to notify PDPs of changes made by the PAP StdEngine in the + * PDP group directories */ @Override public void changed() { @@ -2675,24 +1511,25 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList public void groupChanged(OnapPDPGroup group) { // all PDPs within one group need to be updated/sync'd for (OnapPDP pdp : group.getOnapPdps()) { - pdpChanged(pdp); + pdpChanged(pdp, getPdpDataByGroup(group)); } } 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); + pdpChanged(pdp, loggingContext, getPdpDataByGroup(group)); } } @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)); + // 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(); } @@ -2700,252 +1537,51 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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)); + // 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(); } } - 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; + private void pdpChanged(OnapPDP pdp, List<Properties> pdpDataByGroup) { + Thread t = new Thread(new UpdatePdpThread(pdp, pdpDataByGroup)); + if (CheckPDP.validateID(pdp.getId())) { + t.start(); } + } - 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 void pdpChanged(OnapPDP pdp, ONAPLoggingContext loggingContext, List<Properties> pdpDataByGroup) { + Thread t = new Thread(new UpdatePdpThread(pdp, loggingContext, pdpDataByGroup)); + if (CheckPDP.validateID(pdp.getId())) { + t.start(); } } - /* - * 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<String> 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()); - } + private List<Properties> getPdpDataByGroup(OnapPDPGroup group) { + DataToNotifyPdp dataToNotify = new DataToNotifyPdp(); + return dataToNotify.setPolicyConfigProperties(group); + } - } 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<Properties> getPdpDataByPdpId(OnapPDP pdp) { + DataToNotifyPdp dataToNotify = new DataToNotifyPdp(); + return dataToNotify.setPolicyConfigProperties(pdp, papEngine); } 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,15 +1592,17 @@ 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"; @@ -2975,7 +1613,7 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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 +1629,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,17 +1652,13 @@ 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 + // Sanity Check if (webappsPath == null) { PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS); throw new PAPException( @@ -3023,8 +1671,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)) { @@ -3117,11 +1764,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 +1786,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; + } +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicy.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicy.java index 03fbe0763..3a18504d0 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicy.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/DecisionPolicy.java @@ -2,7 +2,7 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,13 @@ package org.onap.policy.pap.xacml.rest.components; +import com.att.research.xacml.api.XACML3; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.std.IdentifierImpl; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.PrintWriter; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -36,9 +40,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; -import javax.persistence.EntityManager; -import javax.persistence.Query; +import javax.script.SimpleBindings; import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; import org.onap.policy.common.logging.flexlogger.FlexLogger; @@ -51,7 +55,6 @@ import org.onap.policy.controlloop.policy.guard.Guard; import org.onap.policy.controlloop.policy.guard.GuardPolicy; import org.onap.policy.controlloop.policy.guard.MatchParameters; import org.onap.policy.controlloop.policy.guard.builder.ControlLoopGuardBuilder; -import org.onap.policy.pap.xacml.rest.XACMLPapServlet; import org.onap.policy.rest.adapter.PolicyRestAdapter; import org.onap.policy.rest.dao.CommonClassDao; import org.onap.policy.rest.jpa.DecisionSettings; @@ -60,9 +63,8 @@ import org.onap.policy.utils.PolicyUtils; import org.onap.policy.xacml.api.XACMLErrorConstants; import org.onap.policy.xacml.std.pip.engines.aaf.AAFEngine; import org.onap.policy.xacml.util.XACMLPolicyScanner; -import com.att.research.xacml.api.XACML3; -import com.att.research.xacml.api.pap.PAPException; -import com.att.research.xacml.std.IdentifierImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; @@ -82,6 +84,8 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType; + +@Component public class DecisionPolicy extends Policy { private static final Logger LOGGER = FlexLogger.getLogger(DecisionPolicy.class); @@ -92,6 +96,7 @@ public class DecisionPolicy extends Policy { public static final String GUARD_BL_YAML = "GUARD_BL_YAML"; public static final String GUARD_MIN_MAX = "GUARD_MIN_MAX"; public static final String RAINY_DAY = "Rainy_Day"; + public static final String MS_MODEL = "MicroService_Model"; private static final String XACML_GUARD_TEMPLATE = "Decision_GuardPolicyTemplate.xml"; private static final String XACML_BLGUARD_TEMPLATE = "Decision_GuardBLPolicyTemplate.xml"; private static final String XACML_GUARD_MIN_MAX_TEMPLATE = "Decision_GuardMinMaxPolicyTemplate.xml"; @@ -107,13 +112,18 @@ public class DecisionPolicy extends Policy { List<String> dynamicFieldTwoRuleAlgorithms = new LinkedList<>(); List<String> dataTypeList = new LinkedList<>(); - private CommonClassDao commonClassDao; + private static CommonClassDao commonClassDao; public DecisionPolicy() { super(); } - public DecisionPolicy(PolicyRestAdapter policyAdapter, CommonClassDao commonClassDao) { + @Autowired + public DecisionPolicy(CommonClassDao commonClassDao) { + DecisionPolicy.commonClassDao = commonClassDao; + } + + public DecisionPolicy(PolicyRestAdapter policyAdapter) { this.policyAdapter = policyAdapter; this.commonClassDao = commonClassDao; } @@ -447,19 +457,7 @@ public class DecisionPolicy extends Policy { } private DecisionSettings findDecisionSettingsBySettingId(String settingId) { - DecisionSettings decisionSetting = null; - - EntityManager em = XACMLPapServlet.getEmf().createEntityManager(); - Query getDecisionSettings = em.createNamedQuery("DecisionSettings.findAll"); - List<?> decisionSettingsList = getDecisionSettings.getResultList(); - - for (Object id : decisionSettingsList) { - decisionSetting = (DecisionSettings) id; - if (decisionSetting.getXacmlId().equals(settingId)) { - break; - } - } - return decisionSetting; + return (DecisionSettings) commonClassDao.getEntityItem(DecisionSettings.class, "xacmlId", settingId); } private void createRule(PolicyType decisionPolicy, boolean permitRule) { @@ -875,7 +873,7 @@ public class DecisionPolicy extends Policy { public String getFunctionDefinitionId(String key) { FunctionDefinition object = - (FunctionDefinition) commonClassDao.getDataById(FunctionDefinition.class, "shortname", key); + (FunctionDefinition) commonClassDao.getEntityItem(FunctionDefinition.class, "shortname", key); if (object != null) { return object.getXacmlid(); } diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicy.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicy.java index 6cadc77a1..db7bbd4be 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicy.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/FirewallConfigPolicy.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-PAP-REST * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017,2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,6 +20,11 @@ package org.onap.policy.pap.xacml.rest.components; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.std.IdentifierImpl; +import com.fasterxml.jackson.databind.JsonNode; +import com.github.fge.jackson.JsonLoader; +import com.github.fge.jsonpatch.diff.JsonDiff; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -35,22 +40,19 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonReader; -import javax.persistence.EntityManager; -import javax.persistence.Query; - +import javax.script.SimpleBindings; import org.apache.commons.io.FilenameUtils; 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.XACMLPapServlet; import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl; import org.onap.policy.rest.adapter.PolicyRestAdapter; +import org.onap.policy.rest.dao.CommonClassDao; import org.onap.policy.rest.jpa.ActionList; import org.onap.policy.rest.jpa.AddressGroup; import org.onap.policy.rest.jpa.GroupServiceList; @@ -61,13 +63,8 @@ import org.onap.policy.rest.jpa.ProtocolList; import org.onap.policy.rest.jpa.ServiceList; import org.onap.policy.rest.jpa.TermList; import org.onap.policy.rest.jpa.UserInfo; - -import com.att.research.xacml.api.pap.PAPException; -import com.att.research.xacml.std.IdentifierImpl; -import com.fasterxml.jackson.databind.JsonNode; -import com.github.fge.jackson.JsonLoader; -import com.github.fge.jsonpatch.diff.JsonDiff; - +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType; @@ -82,6 +79,7 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType; import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType; +@Component public class FirewallConfigPolicy extends Policy { private static final Logger LOGGER = FlexLogger.getLogger(FirewallConfigPolicy.class); @@ -90,6 +88,13 @@ public class FirewallConfigPolicy extends Policy { super(); } + private static CommonClassDao commonClassDao; + + @Autowired + public FirewallConfigPolicy(CommonClassDao commonClassDao) { + FirewallConfigPolicy.commonClassDao = commonClassDao; + } + public FirewallConfigPolicy(PolicyRestAdapter policyAdapter) { this.policyAdapter = policyAdapter; this.policyAdapter.setConfigType(policyAdapter.getConfigType()); @@ -98,11 +103,11 @@ public class FirewallConfigPolicy extends Policy { // Saving the Configurations file at server location for config policy. protected void saveConfigurations(String policyName, String jsonBody) { String configurationName = policyName; - if(configurationName.endsWith(".xml")){ + if (configurationName.endsWith(".xml")) { configurationName = configurationName.replace(".xml", ""); } String fileName = CONFIG_HOME + File.separator + configurationName + ".json"; - try(BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))){ + try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) { bw.write(jsonBody); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Configuration is succesfully saved"); @@ -200,16 +205,15 @@ public class FirewallConfigPolicy extends Policy { oldversion = oldversion - 1; dbPolicyName = dbPolicyName + oldversion + ".xml"; } - EntityManager em = XACMLPapServlet.getEmf().createEntityManager(); - Query createPolicyQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"); - createPolicyQuery.setParameter("scope", scope); - createPolicyQuery.setParameter("policyName", dbPolicyName); - List<?> createPolicyQueryList = createPolicyQuery.getResultList(); - if(!createPolicyQueryList.isEmpty()){ + String createPolicyQuery = "SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"; + SimpleBindings params = new SimpleBindings(); + params.put("scope", scope); + params.put("policyName", dbPolicyName); + List<?> createPolicyQueryList = commonClassDao.getDataByQuery(createPolicyQuery, params); + if (!createPolicyQueryList.isEmpty()) { PolicyEntity entitydata = (PolicyEntity) createPolicyQueryList.get(0); policyAdapter.setPrevJsonBody(entitydata.getConfigurationData().getConfigBody()); } - em.close(); if (policyAdapter.getData() != null) { String jsonBody = policyAdapter.getJsonBody(); saveConfigurations(policyName, jsonBody); @@ -252,7 +256,7 @@ public class FirewallConfigPolicy extends Policy { target.getAnyOf().add(anyOf); // Adding the target to the policy element - configPolicy.setTarget((TargetType) target); + configPolicy.setTarget(target); RuleType rule = new RuleType(); rule.setRuleId(policyAdapter.getRuleID()); @@ -1291,4 +1295,4 @@ public class FirewallConfigPolicy extends Policy { return policyAdapter.getPolicyData(); } -}
\ No newline at end of file +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/HandleIncomingNotifications.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/HandleIncomingNotifications.java new file mode 100644 index 000000000..fc08b643e --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/HandleIncomingNotifications.java @@ -0,0 +1,593 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest.components; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.util.XACMLProperties; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import javax.persistence.PersistenceException; +import org.apache.commons.io.FilenameUtils; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +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.XACMLPapServlet; +import org.onap.policy.rest.XACMLRestProperties; +import org.onap.policy.rest.dao.PolicyDBException; +import org.onap.policy.rest.jpa.GroupEntity; +import org.onap.policy.rest.jpa.PdpEntity; +import org.onap.policy.rest.jpa.PolicyEntity; +import org.onap.policy.xacml.api.pap.OnapPDP; +import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.onap.policy.xacml.std.pap.StdPDPGroup; +import org.onap.policy.xacml.std.pap.StdPDPPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class HandleIncomingNotifications { + + private static final Logger logger = FlexLogger.getLogger(HandleIncomingNotifications.class); + + private static final String POLICY_NOTIFICATION = "policy"; + private static final String PDP_NOTIFICATION = "pdp"; + private static final String GROUP_NOTIFICATION = "group"; + public static final String JSON_CONFIG = "JSON"; + public static final String XML_CONFIG = "XML"; + public static final String PROPERTIES_CONFIG = "PROPERTIES"; + public static final String OTHER_CONFIG = "OTHER"; + public static final String AUDIT_USER = "audit"; + + + private static SessionFactory sessionfactory; + + @Autowired + public HandleIncomingNotifications(SessionFactory sessionfactory) { + HandleIncomingNotifications.sessionfactory = sessionfactory; + } + + public HandleIncomingNotifications() { + // Default Constructor + } + + public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, + XACMLPapServlet xacmlPapServlet) { + logger.info("DBDao url: " + url + " has reported an update on " + entityType + " entity " + entityId); + PolicyDBDaoTransaction transaction = PolicyDBDao.getPolicyDBDaoInstance().getNewTransaction(); + // although its named retries, this is the total number of tries + int retries; + try { + retries = Integer + .parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INCOMINGNOTIFICATION_TRIES)); + } catch (Exception e) { + logger.error("xacml.rest.pap.incomingnotification.tries property not set, using a default of 3." + e); + retries = 3; + } + // if someone sets it to some dumb value, we need to make sure it will + // try at least once + if (retries < 1) { + retries = 1; + } + int pauseBetweenRetries = 1000; + switch (entityType) { + + case POLICY_NOTIFICATION: + for (int i = 0; i < retries; i++) { + try { + handleIncomingPolicyChange(entityId); + break; + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught exception on handleIncomingPolicyChange(" + url + ", " + entityId + ", " + + extraData + ")"); + } + try { + Thread.sleep(pauseBetweenRetries); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + break; + case PDP_NOTIFICATION: + for (int i = 0; i < retries; i++) { + try { + handleIncomingPdpChange(entityId, transaction); + break; + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught exception on handleIncomingPdpChange(" + url + ", " + entityId + ", " + + transaction + ")"); + } + try { + Thread.sleep(pauseBetweenRetries); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + break; + case GROUP_NOTIFICATION: + for (int i = 0; i < retries; i++) { + try { + handleIncomingGroupChange(entityId, extraData, transaction); + break; + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught exception on handleIncomingGroupChange(" + url + ", " + entityId + ", " + + extraData + ", " + transaction + ", " + xacmlPapServlet + ")"); + } + try { + Thread.sleep(pauseBetweenRetries); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + break; + } + // no changes should be being made in this function, we still need to + // close + transaction.rollbackTransaction(); + } + + private void handleIncomingGroupChange(String groupId, String extraData, PolicyDBDaoTransaction transaction) + throws PAPException, PolicyDBException { + GroupEntity groupRecord = null; + long groupIdLong = -1; + try { + groupIdLong = Long.parseLong(groupId); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("groupId " + groupId + " cannot be parsed into a long"); + } + try { + groupRecord = transaction.getGroup(groupIdLong); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get pdp group record with transaction.getGroup(" + groupIdLong + ");"); + throw new PAPException("Could not get local group " + groupIdLong); + } + if (groupRecord == null) { + throw new PersistenceException("The group record returned is null"); + } + // compare to local fs + // does group folder exist + OnapPDPGroup localGroup = null; + try { + localGroup = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(groupRecord.getGroupId()); + } catch (Exception e) { + logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup(" + groupId + ");", + e); + } + if (localGroup == null && extraData != null) { + // here we can try to load an old group id from the extraData + try { + localGroup = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(extraData); + } catch (Exception e) { + logger.warn( + "Caught PAPException trying to get local pdp group with papEngine.getGroup(" + extraData + ");", + e); + } + } + if (localGroup != null && groupRecord.isDeleted()) { + OnapPDPGroup newLocalGroup = null; + if (extraData != null) { + try { + newLocalGroup = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(extraData); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get new pdp group with papEngine.getGroup(" + extraData + + ");"); + } + } + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().removeGroup(localGroup, newLocalGroup); + } catch (NullPointerException | PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get remove pdp group with papEngine.removeGroup(" + localGroup + + ", " + newLocalGroup + ");"); + throw new PAPException("Could not remove group " + groupId); + } + } else if (localGroup == null) { + // creating a new group + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().newGroup(groupRecord.getgroupName(), + groupRecord.getDescription()); + } catch (NullPointerException | PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription());"); + throw new PAPException("Could not create group " + groupRecord); + } + try { + localGroup = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(groupRecord.getGroupId()); + } catch (PAPException e1) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get pdp group we just created with papEngine.getGroup(groupRecord.getGroupId());\nAny PDPs or policies in the new group may not have been added"); + return; + } + // add possible pdps to group + List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId())); + for (Object pdpO : pdpsInGroup) { + PdpEntity pdp = (PdpEntity) pdpO; + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().newPDP(pdp.getPdpId(), localGroup, + pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort()); + } catch (NullPointerException | PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());"); + throw new PAPException("Could not create pdp " + pdp); + } + } + // add possible policies to group (file system only, apparently) + } else { + if (!(localGroup instanceof StdPDPGroup)) { + throw new PAPException("group is not a StdPDPGroup"); + } + // clone the object + // because it will be comparing the new group to its own version + StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(), localGroup.isDefaultGroup(), + localGroup.getName(), localGroup.getDescription(), ((StdPDPGroup) localGroup).getDirectory()); + localGroupClone.setOnapPdps(localGroup.getOnapPdps()); + localGroupClone.setPipConfigs(localGroup.getPipConfigs()); + localGroupClone.setStatus(localGroup.getStatus()); + // we are updating a group or adding a policy or changing default + // set default if it should be + if (!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()) { + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().setDefaultGroup(localGroup); + return; + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to set default group with papEngine.SetDefaultGroup(" + + localGroupClone + ");"); + throw new PAPException("Could not set default group to " + localGroupClone); + } + } + boolean needToUpdate = false; + if (updateGroupPoliciesInFileSystem(localGroupClone, localGroup, groupRecord, transaction)) { + needToUpdate = true; + } + if (!PolicyDBDao.stringEquals(localGroupClone.getId(), groupRecord.getGroupId()) + || !PolicyDBDao.stringEquals(localGroupClone.getName(), groupRecord.getgroupName())) { + // changing ids + // we do not want to change the id, the papEngine will do this + // for us, it needs to know the old id + localGroupClone.setName(groupRecord.getgroupName()); + needToUpdate = true; + } + if (!PolicyDBDao.stringEquals(localGroupClone.getDescription(), groupRecord.getDescription())) { + localGroupClone.setDescription(groupRecord.getDescription()); + needToUpdate = true; + } + if (needToUpdate) { + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().updateGroup(localGroupClone); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to update group with papEngine.updateGroup(" + localGroupClone + + ");"); + throw new PAPException("Could not update group " + localGroupClone); + } + } + } + } + + // this will also handle removes, since incoming pdpGroup has no policies + // internally, we are just going to add them all in from the db + private boolean updateGroupPoliciesInFileSystem(OnapPDPGroup pdpGroup, OnapPDPGroup oldPdpGroup, + GroupEntity groupRecord, PolicyDBDaoTransaction transaction) throws PAPException, PolicyDBException { + if (!(pdpGroup instanceof StdPDPGroup)) { + throw new PAPException("group is not a StdPDPGroup"); + } + StdPDPGroup group = (StdPDPGroup) pdpGroup; + // this must always be true since we don't explicitly know when a delete + // is occuring + boolean didUpdate = true; + HashMap<String, PDPPolicy> currentPolicySet = new HashMap<>(oldPdpGroup.getPolicies().size()); + HashSet<PDPPolicy> newPolicySet = new HashSet<>(); + for (PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()) { + currentPolicySet.put(pdpPolicy.getId(), pdpPolicy); + } + for (PolicyEntity policy : groupRecord.getPolicies()) { + String pdpPolicyName = + PolicyDBDao.getPolicyDBDaoInstance().getPdpPolicyName(policy.getPolicyName(), policy.getScope()); + if (group.getPolicy(pdpPolicyName) == null) { + didUpdate = true; + if (currentPolicySet.containsKey(pdpPolicyName)) { + newPolicySet.add(currentPolicySet.get(pdpPolicyName)); + } else { + logger.info( + "PolicyDBDao: Adding the new policy to the PDP group after notification: " + pdpPolicyName); + InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); + group.copyPolicyToFile(pdpPolicyName, policyStream); + ((StdPDPPolicy) (group.getPolicy(pdpPolicyName))).setName(PolicyDBDao.getPolicyDBDaoInstance() + .removeExtensionAndVersionFromPolicyName(pdpPolicyName)); + try { + policyStream.close(); + } catch (IOException e) { + didUpdate = false; + PolicyLogger.error(e.getMessage() + e); + } + } + } + } + logger.info("PolicyDBDao: Adding updated policies to group after notification."); + if (didUpdate) { + newPolicySet.addAll(group.getPolicies()); + group.setPolicies(newPolicySet); + } + return didUpdate; + } + + private void handleIncomingPdpChange(String pdpId, PolicyDBDaoTransaction transaction) throws PAPException { + // get pdp + long pdpIdLong = -1; + try { + pdpIdLong = Long.parseLong(pdpId); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("pdpId " + pdpId + " cannot be parsed into a long"); + } + PdpEntity pdpRecord = null; + try { + pdpRecord = transaction.getPdp(pdpIdLong); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get pdp record with transaction.getPdp(" + pdpIdLong + ");"); + throw new PAPException("Could not get local pdp " + pdpIdLong); + } + if (pdpRecord == null) { + throw new PersistenceException("The pdpRecord returned is null"); + } + OnapPDP localPdp = null; + try { + localPdp = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getPDP(pdpRecord.getPdpId()); + } catch (PAPException e) { + logger.warn("Caught PAPException trying to get local pdp with papEngine.getPDP(" + pdpId + ");", e); + } + if (localPdp != null && pdpRecord.isDeleted()) { + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().removePDP(localPdp); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get remove pdp with papEngine.removePDP(" + localPdp + ");"); + throw new PAPException("Could not remove pdp " + pdpId); + } + } else if (localPdp == null) { + // add new pdp + // get group + OnapPDPGroup localGroup = null; + try { + localGroup = + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(pdpRecord.getGroup().getGroupId()); + } catch (PAPException e1) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());"); + throw new PAPException("Could not get local group"); + } + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().newPDP(pdpRecord.getPdpId(), localGroup, + pdpRecord.getPdpName(), pdpRecord.getDescription(), pdpRecord.getJmxPort()); + } catch (NullPointerException | PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to create pdp with papEngine.newPDP(" + pdpRecord.getPdpId() + ", " + + localGroup + ", " + pdpRecord.getPdpName() + ", " + pdpRecord.getDescription() + ", " + + pdpRecord.getJmxPort() + ");"); + throw new PAPException("Could not create pdp " + pdpRecord); + } + } else { + boolean needToUpdate = false; + if (!PolicyDBDao.stringEquals(localPdp.getId(), pdpRecord.getPdpId()) + || !PolicyDBDao.stringEquals(localPdp.getName(), pdpRecord.getPdpName())) { + // again, we don't want to change the id, the papEngine will do + // this + localPdp.setName(pdpRecord.getPdpName()); + needToUpdate = true; + } + if (!PolicyDBDao.stringEquals(localPdp.getDescription(), pdpRecord.getDescription())) { + localPdp.setDescription(pdpRecord.getDescription()); + needToUpdate = true; + } + String localPdpGroupId = null; + try { + localPdpGroupId = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getPDPGroup(localPdp).getId(); + } catch (PAPException e) { + // could be null or something, just warn at this point + logger.warn( + "Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = papEngine.getPDPGroup(localPdp).getId();", + e); + } + if (!PolicyDBDao.stringEquals(localPdpGroupId, pdpRecord.getGroup().getGroupId())) { + OnapPDPGroup newPdpGroup = null; + try { + newPdpGroup = PolicyDBDao.getPolicyDBDaoInstance().getPapEngine() + .getGroup(pdpRecord.getGroup().getGroupId()); + } catch (PAPException e) { + // ok, now we have an issue. Time to stop things + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to get id of local group to move pdp to with papEngine.getGroup(pdpRecord.getGroup().getGroupId());"); + throw new PAPException("Could not get local group"); + } + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().movePDP(localPdp, newPdpGroup); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);"); + throw new PAPException("Could not move pdp " + localPdp); + } + } + if (localPdp.getJmxPort() != pdpRecord.getJmxPort()) { + localPdp.setJmxPort(pdpRecord.getJmxPort()); + needToUpdate = true; + } + if (needToUpdate) { + try { + PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().updatePDP(localPdp); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PAPException trying to update pdp with papEngine.updatePdp(" + localPdp + ");"); + throw new PAPException("Could not update pdp " + localPdp); + } + } + } + // compare to local situation + // call command to update + } + + private void handleIncomingPolicyChange(String policyId) { + String policyName = null; + Session session = sessionfactory.openSession(); + Query getPolicyEntityQuery = session.getNamedQuery("PolicyEntity.FindById"); + getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId)); + + @SuppressWarnings("unchecked") + List<PolicyEntity> policies = getPolicyEntityQuery.list(); + PolicyEntity policy = null; + if (!policies.isEmpty()) { + policy = policies.get(0); + } + String action = "unknown action"; + try { + if (policy != null) { + policyName = policy.getPolicyName(); + logger.info("Deleting old Policy Config File for " + policy.getPolicyName()); + action = "delete"; + Path subFile = null; + + if (policy.getConfigurationData() != null) { + subFile = + getPolicySubFile(policy.getConfigurationData().getConfigurationName(), PolicyDBDao.CONFIG); + } else if (policy.getActionBodyEntity() != null) { + subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), PolicyDBDao.ACTION); + } + + if (subFile != null) { + Files.deleteIfExists(subFile); + } + if (policy.getConfigurationData() != null) { + writePolicySubFile(policy, PolicyDBDao.CONFIG); + } else if (policy.getActionBodyEntity() != null) { + writePolicySubFile(policy, action); + } + } + } catch (IOException e1) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, PolicyDBDao.POLICYDBDAO_VAR, + "Error occurred while performing [" + action + "] of Policy File: " + policyName); + } finally { + session.close(); + } + } + + private boolean writePolicySubFile(PolicyEntity policy, String policyType) { + logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType + + "]"); + String type = null; + String subTypeName = null; + String subTypeBody = null; + if (PolicyDBDao.CONFIG.equalsIgnoreCase(policyType)) { + type = PolicyDBDao.CONFIG; + subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName()); + subTypeBody = policy.getConfigurationData().getConfigBody(); + + String configType = policy.getConfigurationData().getConfigType(); + + if (configType != null) { + if (configType.equals(JSON_CONFIG)) { + subTypeName = subTypeName + ".json"; + } + if (configType.equals(XML_CONFIG)) { + subTypeName = subTypeName + ".xml"; + } + if (configType.equals(PROPERTIES_CONFIG)) { + subTypeName = subTypeName + ".properties"; + } + if (configType.equals(OTHER_CONFIG)) { + subTypeName = subTypeName + ".txt"; + } + } + } else if (PolicyDBDao.ACTION.equalsIgnoreCase(policyType)) { + type = PolicyDBDao.ACTION; + subTypeName = policy.getActionBodyEntity().getActionBodyName(); + subTypeBody = policy.getActionBodyEntity().getActionBody(); + } + Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type); + + if (subTypeBody == null) { + subTypeBody = ""; + } + boolean success = false; + try { + Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName)); + File file = Paths.get(filePath.toString(), subTypeName).toFile(); + boolean value = file.createNewFile(); + logger.debug("New file created successfully" + value); + try (FileWriter fileWriter = new FileWriter(file, false)) { + // false to overwrite + fileWriter.write(subTypeBody); + fileWriter.close(); + success = true; + } + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName()); + } + return success; + } + + Path getPolicySubFile(String inputFileName, String subFileType) { + String filename = inputFileName; + logger.info("getPolicySubFile(" + filename + ", " + subFileType + ")"); + Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS), subFileType); + File file = null; + + filename = FilenameUtils.removeExtension(filename); + + for (File tmpFile : filePath.toFile().listFiles()) { + if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)) { + file = tmpFile; + } + } + + Path finalPath = null; + if (file != null) { + finalPath = Paths.get(file.getAbsolutePath()); + } + + logger.info("end of getPolicySubFile: " + finalPath); + return finalPath; + } +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/NotifyOtherPaps.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/NotifyOtherPaps.java new file mode 100644 index 000000000..cd02c2bfe --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/NotifyOtherPaps.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest.components; + +import com.att.research.xacml.util.XACMLProperties; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.rest.XACMLRestProperties; +import org.onap.policy.rest.jpa.PolicyDBDaoEntity; +import org.onap.policy.utils.CryptoUtils; + +public class NotifyOtherPaps { + + private static final Logger LOGGER = FlexLogger.getLogger(NotifyOtherPaps.class); + private List<PolicyDBDaoEntity> failedPaps = null; + + public void notifyOthers(long entityId, String entityType) { + notifyOthers(entityId, entityType, null); + } + + /** + * Notify others. + * + * @param entityId the entity id + * @param entityType the entity type + * @param newGroupId the new group id + */ + public void notifyOthers(long entityId, String entityType, String newGroupId) { + LOGGER.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers(" + entityId + "," + + entityType + "," + newGroupId + ") called"); + failedPaps = new ArrayList<>(); + + List<?> otherServers = PolicyDBDao.getPolicyDBDaoInstance().getOtherServers(); + // Notify other paps + startNotifyThreads(otherServers, entityId, entityType, newGroupId); + // Retry for failed paps + if (!failedPaps.isEmpty()) { + startNotifyThreads(failedPaps, entityId, entityType, newGroupId); + } + } + + private void startNotifyThreads(List<?> otherServers, long entityId, String entityType, String newGroupId) { + LinkedList<Thread> notifyThreads = new LinkedList<>(); + // we're going to run notifications in parallel threads to speed things + // up + for (Object obj : otherServers) { + Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId)); + newNotifyThread.start(); + notifyThreads.add(newNotifyThread); + } + // we want to wait for all notifications to complete or timeout before + // we unlock the interface and allow more changes + for (Thread t : notifyThreads) { + try { + t.join(); + } catch (Exception e) { + LOGGER.warn("Could not join a notifcation thread" + e); + } + } + } + + private class NotifyOtherThread implements Runnable { + public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId) { + this.obj = obj; + this.entityId = entityId; + this.entityType = entityType; + this.newGroupId = newGroupId; + } + + private Object obj; + private long entityId; + private String entityType; + private String newGroupId; + + @Override + public void run() { + PolicyDBDao dao = new PolicyDBDao(); + PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity) obj; + String otherPap = dbdEntity.getPolicyDBDaoUrl(); + String username = dbdEntity.getUsername(); + String txt; + try { + txt = new String(CryptoUtils.decryptTxt(dbdEntity.getPassword()), StandardCharsets.UTF_8); + } catch (Exception e) { + LOGGER.debug(e); + // if we can't decrypt, might as well try it anyway + txt = dbdEntity.getPassword(); + } + + HttpURLConnection connection = null; + UUID requestId = UUID.randomUUID(); + URL url; + String papUrl; + try { + String[] papUrlUserPass = dao.getPapUrlUserPass(); + if (papUrlUserPass == null) { + papUrl = "undefined"; + } else { + papUrl = papUrlUserPass[0]; + } + LOGGER.debug("We are going to try to notify " + otherPap); + // is this our own url? + String ourUrl = otherPap; + try { + ourUrl = dao.splitPapUrlUserPass(otherPap)[0]; + } catch (Exception e) { + ourUrl = otherPap; + LOGGER.debug(e); + } + if (otherPap == null) { + otherPap = "undefined"; + } + if (papUrl.equals(ourUrl)) { + LOGGER.debug(otherPap + " is our url, skipping notify"); + return; + } + if (newGroupId == null) { + url = new URL(otherPap + "?policydbdaourl=" + papUrl + "&entityid=" + entityId + "&entitytype=" + + entityType); + } else { + url = new URL(otherPap + "?policydbdaourl=" + papUrl + "&entityid=" + entityId + "&entitytype=" + + entityType + "&extradata=" + newGroupId); + } + } catch (MalformedURLException e) { + LOGGER.warn("Caught MalformedURLException on: new URL()", e); + return; + } + // + // Open up the connection + // + LOGGER.info("PolicyDBDao: NotifyOtherThread: notifying other PAPs of an update"); + LOGGER.info("Connecting with url: " + url); + try { + connection = (HttpURLConnection) url.openConnection(); + } catch (Exception e) { + LOGGER.warn("Caught exception on: url.openConnection()", e); + return; + } + // + // Setup our method and headers + // + try { + connection.setRequestMethod("PUT"); + } catch (ProtocolException e) { + // why would this error ever occur? + LOGGER.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");", e); + return; + } + Base64.Encoder encoder = Base64.getEncoder(); + String encoding = encoder.encodeToString((username + ":" + txt).getBytes(StandardCharsets.UTF_8)); + connection.setRequestProperty("Authorization", "Basic " + encoding); + connection.setRequestProperty("Accept", "text/x-java-properties"); + connection.setRequestProperty("Content-Type", "text/x-java-properties"); + connection.setRequestProperty("requestID", requestId.toString()); + int readTimeout; + try { + readTimeout = + Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT)); + } catch (Exception e) { + LOGGER.error("xacml.rest.pap.notify.timeoutms property not set, using a default.", e); + readTimeout = 10000; + } + connection.setReadTimeout(readTimeout); + connection.setConnectTimeout(readTimeout); + connection.setUseCaches(false); + // + // Adding this in. It seems the HttpUrlConnection class does NOT + // properly forward our headers for POST re-direction. It does so + // for a GET re-direction. + // + // So we need to handle this ourselves. + // + connection.setInstanceFollowRedirects(false); + connection.setDoOutput(true); + connection.setDoInput(true); + try { + connection.connect(); + } catch (Exception e) { + LOGGER.warn("Caught exception on: connection.connect()", e); + return; + } + try { + if (connection.getResponseCode() == 200) { + LOGGER.info("PolicyDBDao: NotifyOtherThread received response 200 from pap server on notify"); + } else { + LOGGER.warn("PolicyDBDao: NotifyOtherThread connection response code not 200, received: " + + connection.getResponseCode()); + failedPaps.add(dbdEntity); + } + } catch (Exception e) { + LOGGER.warn("Caught Exception on: connection.getResponseCode() ", e); + } + + connection.disconnect(); + } + } +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java index c9c49720d..ba8057102 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDao.java @@ -21,51 +21,33 @@ package org.onap.policy.pap.xacml.rest.components; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.util.XACMLProperties; import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.ProtocolException; import java.net.URI; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Base64; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.UUID; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.LockModeType; import javax.persistence.PersistenceException; -import javax.persistence.Query; -import javax.persistence.RollbackException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathFactory; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; +import org.hibernate.Criteria; +import org.hibernate.LockMode; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; 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.XACMLPapServlet; import org.onap.policy.rest.XACMLRestProperties; import org.onap.policy.rest.adapter.PolicyRestAdapter; import org.onap.policy.rest.dao.PolicyDBException; @@ -77,83 +59,70 @@ import org.onap.policy.rest.jpa.PdpEntity; import org.onap.policy.rest.jpa.PolicyDBDaoEntity; import org.onap.policy.rest.jpa.PolicyEntity; import org.onap.policy.utils.CryptoUtils; +import org.onap.policy.xacml.api.XACMLErrorConstants; import org.onap.policy.xacml.api.pap.OnapPDP; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.api.pap.PAPPolicyEngine; import org.onap.policy.xacml.std.pap.StdPDPGroup; import org.onap.policy.xacml.std.pap.StdPDPPolicy; -import org.onap.policy.xacml.util.XACMLPolicyWriter; -import org.w3c.dom.Document; -import org.xml.sax.InputSource; -import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; -import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; -import com.att.research.xacml.api.pap.PAPException; -import com.att.research.xacml.api.pap.PDP; -import com.att.research.xacml.api.pap.PDPPolicy; -import com.att.research.xacml.util.XACMLProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +@Component public class PolicyDBDao { private static final Logger logger = FlexLogger.getLogger(PolicyDBDao.class); private List<?> otherServers; - private EntityManagerFactory emf; + + public List<?> getOtherServers() { + return otherServers; + } + + public void setOtherServers(List<?> otherServers) { + this.otherServers = otherServers; + } + private static PolicyDBDao currentInstance = null; private PAPPolicyEngine papEngine; - private static final String JSON_CONFIG = "JSON"; - private static final String XML_CONFIG = "XML"; - private static final String PROPERTIES_CONFIG = "PROPERTIES"; - private static final String OTHER_CONFIG = "OTHER"; - - // Declared to static variables which were repeating multiple times across the PolicyDBDao - public static final String config = "Config"; - public static final String action = "Action"; - private static final String groupIdVar = "groupId"; - private static final String deletedVar = "deleted"; - private static final String groupEntitySelectQuery = + public PAPPolicyEngine getPapEngine() { + return papEngine; + } + + public static final String JSON_CONFIG = "JSON"; + public static final String XML_CONFIG = "XML"; + public static final String PROPERTIES_CONFIG = "PROPERTIES"; + public static final String OTHER_CONFIG = "OTHER"; + public static final String AUDIT_USER = "audit"; + + public static final String CONFIG = "Config"; + public static final String ACTION = "Action"; + public static final String GROUP_ID = "groupId"; + public static final String DELETED = "deleted"; + public static final String GROUPENTITY_SELECT = "SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"; - private static final String pdpEntitySelectQuery = + public static final String PDPENTITY_SELECT = "SELECT p FROM PdpEntity p WHERE p.pdpId=:pdpId AND p.deleted=:deleted"; - private static final String groupCannotBeFound = "The group could not be found with id "; - private static final String foundInDBNotDeleted = " were found in the database that are not deleted"; - private static final String moreThanOnePDP = "Somehow, more than one pdp with the same id "; - private static final String deletedStatusFound = " and deleted status were found in the database"; - private static final String duplicateGroupId = "Somehow, more than one group with the same id "; - private static final String pdpIdVariable = "pdpId"; - private static final String queryFailedToCheckExisting = "Query failed trying to check for existing group"; - private static final String queryFailedToGetGroup = "Query failed trying to get group "; - public static final String scope = "scope"; - private static final String policyDBDaoVar = "PolicyDBDao"; - private static final String duplicatePolicyId = "Somehow, more than one policy with the id "; - private static final String foundInDB = " were found in the database"; - private static final String TIMESTAMP = "\n TimeStamp = "; - private static final String CAUGHTEXCEPTIONONNOTIFY = "Caught Exception on notifyOthers("; - - private static boolean isJunit = false; + public static final String GROUP_NOT_FOUND = "The group could not be found with id "; + public static final String FOUND_IN_DB_NOT_DEL = " were found in the database that are not deleted"; + public static final String MORE_THAN_ONE_PDP = "Somehow, more than one pdp with the same id "; + public static final String DELETED_STATUS_FOUND = " and deleted status were found in the database"; + public static final String DUPLICATE_GROUPID = "Somehow, more than one group with the same id "; + public static final String PDP_ID = "pdpId"; + public static final String QUERY_FAILED_FOR_GROUP = "Query failed trying to check for existing group"; + public static final String QUERY_FAILED_GET_GROUP = "Query failed trying to get group "; + public static final String SCOPE = "scope"; + public static final String POLICYDBDAO_VAR = "PolicyDBDao"; + public static final String DUP_POLICYID = "Somehow, more than one policy with the id "; + public static final String FOUND_IN_DB = " were found in the database"; + + + public static boolean isJunit = false; public static void setJunit(boolean isJunit) { PolicyDBDao.isJunit = isJunit; } - /** - * Get an instance of a PolicyDBDao. It creates one if it does not exist. Only one instance is allowed to be created - * per server. - * - * @param emf The EntityFactoryManager to be used for database connections - * @return The new instance of PolicyDBDao or throw exception if the given emf is null. - * @throws IllegalStateException if a PolicyDBDao has already been constructed. Call getPolicyDBDaoInstance() to get - * this. - */ - public static PolicyDBDao getPolicyDBDaoInstance(EntityManagerFactory emf) { - logger.debug("getPolicyDBDaoInstance(EntityManagerFactory emf) as getPolicyDBDaoInstance(" + emf + ") called"); - if (currentInstance == null) { - if (emf != null) { - currentInstance = new PolicyDBDao(emf); - return currentInstance; - } - throw new IllegalStateException("The EntityManagerFactory is Null"); - } - return currentInstance; - } + private static SessionFactory sessionfactory; /** * Gets the current instance of PolicyDBDao. @@ -166,19 +135,26 @@ public class PolicyDBDao { logger.debug("getPolicyDBDaoInstance() as getPolicyDBDaoInstance() called"); if (currentInstance != null) { return currentInstance; + } else { + currentInstance = new PolicyDBDao("init"); } - throw new IllegalStateException( - "The PolicyDBDao.currentInstance is Null. Use getPolicyDBDao(EntityManagerFactory emf)"); + return currentInstance; } public void setPapEngine(PAPPolicyEngine papEngine2) { this.papEngine = papEngine2; } - private PolicyDBDao(EntityManagerFactory emf) { - logger.debug("PolicyDBDao(EntityManagerFactory emf) as PolicyDBDao(" + emf + ") called"); - this.emf = emf; + @Autowired + public PolicyDBDao(SessionFactory sessionFactory) { + PolicyDBDao.sessionfactory = sessionFactory; + } + + public PolicyDBDao() { + // Default Constructor + } + public PolicyDBDao(String init) { // not needed in this release if (!register()) { PolicyLogger @@ -196,29 +172,21 @@ public class PolicyDBDao { // not static because we are going to be using the instance's emf // waitTime in ms to wait for lock, or -1 to wait forever (no) - private void startTransactionSynced(EntityManager entityMgr, int waitTime) { - logger.debug("\n\nstartTransactionSynced(EntityManager entityMgr,int waitTime) as " - + "\n startTransactionSynced(" + entityMgr + "," + waitTime + ") called\n\n"); + @SuppressWarnings("deprecation") + public void startTransactionSynced(Session session, int waitTime) throws InterruptedException { + logger.debug("\n\nstartTransactionSynced(Hibernate Session,int waitTime) as " + "\n startTransactionSynced(" + + session + "," + waitTime + ") called\n\n"); DatabaseLockEntity lock = null; - - entityMgr.setProperty("javax.persistence.query.timeout", waitTime); - entityMgr.getTransaction().begin(); - - if (logger.isDebugEnabled()) { - Map<String, Object> properties = entityMgr.getProperties(); - logger.debug( - "\n\nstartTransactionSynced():" + "\n entityManager.getProperties() = " + properties + "\n\n"); - } + session.beginTransaction(); try { if (logger.isDebugEnabled()) { logger.debug("\n\nstartTransactionSynced():" + "\n ATTEMPT to get the DB lock" + "\n\n"); } - lock = entityMgr.find(DatabaseLockEntity.class, 1, LockModeType.PESSIMISTIC_WRITE); + lock = (DatabaseLockEntity) session.get(DatabaseLockEntity.class, 1, LockMode.PESSIMISTIC_WRITE); if (logger.isDebugEnabled()) { logger.debug("\n\nstartTransactionSynced():" + "\n GOT the DB lock" + "\n\n"); } } catch (Exception e) { - System.out.println("Could not get lock entity"); logger.error("Exception Occured" + e); } if (lock == null) { @@ -236,40 +204,34 @@ public class PolicyDBDao { private List<?> getRemotePolicyDBDaoList() { logger.debug("getRemotePolicyDBDaoList() as getRemotePolicyDBDaoList() called"); List<?> policyDBDaoEntityList = new LinkedList<>(); - EntityManager em = emf.createEntityManager(); - startTransactionSynced(em, 1000); + Session session = sessionfactory.openSession(); try { - Query getPolicyDBDaoEntityQuery = em.createNamedQuery("PolicyDBDaoEntity.findAll"); - policyDBDaoEntityList = getPolicyDBDaoEntityQuery.getResultList(); - + Criteria cr = session.createCriteria(PolicyDBDaoEntity.class); + policyDBDaoEntityList = cr.list(); } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Exception querying for other registered PolicyDBDaos"); logger.warn("List of remote PolicyDBDaos will be empty", e); - } - try { - em.getTransaction().commit(); - } catch (Exception e) { - logger.warn("List of remote PolicyDBDaos will be empty", e); + } finally { try { - em.getTransaction().rollback(); - } catch (Exception e2) { - logger.debug("List of remote PolicyDBDaos will be empty", e2); + session.close(); + } catch (Exception e) { + logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error While Closing Connection/Statement" + e); } } - em.close(); return policyDBDaoEntityList; } public PolicyDBDaoTransaction getNewTransaction() { logger.debug("getNewTransaction() as getNewTransaction() called"); - return new PolicyDBDaoTransactionInstance(); + return new PolicyDbDaoTransactionInstance("init"); } /* - * Because the normal transactions are not used in audits, we can use the same transaction mechanism to get a - * transaction and obtain the emlock and the DB lock. We just need to provide different transaction timeout values - * in ms because the audit will run longer than normal transactions. + * Because the normal transactions are not used in audits, we can use the same transaction + * mechanism to get a transaction and obtain the emlock and the DB lock. We just need to provide + * different transaction timeout values in ms because the audit will run longer than normal + * transactions. */ public PolicyDBDaoTransaction getNewAuditTransaction() { logger.debug("getNewAuditTransaction() as getNewAuditTransaction() called"); @@ -277,17 +239,16 @@ public class PolicyDBDao { int auditWaitMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT)); // Use the (extended) audit timeout time in ms int auditTimeoutMs = Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_AUDIT_TIMEOUT)); - return new PolicyDBDaoTransactionInstance(auditTimeoutMs, auditWaitMs); + return new PolicyDbDaoTransactionInstance(auditTimeoutMs, auditWaitMs); } - /** * Checks if two strings are equal. Null strings ARE allowed. * * @param one A String or null to compare * @param two A String or null to compare */ - private static boolean stringEquals(String one, String two) { + public static boolean stringEquals(String one, String two) { logger.debug("stringEquals(String one, String two) as stringEquals(" + one + ", " + two + ") called"); if (one == null && two == null) { return true; @@ -299,11 +260,12 @@ public class PolicyDBDao { } /** - * Returns the url of this local pap server, removing the username and password, if they are present + * Returns the url of this local pap server, removing the username and password, if they are + * present * * @return The url of this local pap server */ - private String[] getPapUrlUserPass() { + public String[] getPapUrlUserPass() { logger.debug("getPapUrl() as getPapUrl() called"); String url = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL); if (url == null) { @@ -312,7 +274,7 @@ public class PolicyDBDao { return splitPapUrlUserPass(url); } - private String[] splitPapUrlUserPass(String url) { + public String[] splitPapUrlUserPass(String url) { String[] urlUserPass = new String[3]; String[] commaSplit = url.split(","); urlUserPass[0] = commaSplit[0]; @@ -332,7 +294,8 @@ public class PolicyDBDao { urlUserPass[2] = passwordPropertyValue; } } - // if there is no comma, for some reason there is no username and password, so don't try to cut them off + // if there is no comma, for some reason there is no user name and + // password, so don't try to cut them off return urlUserPass; } @@ -348,65 +311,69 @@ public class PolicyDBDao { if (url == null || url.length < 3) { return false; } - EntityManager em = emf.createEntityManager(); + Session session = sessionfactory.openSession(); try { - startTransactionSynced(em, 1000); - } catch (IllegalStateException e) { + startTransactionSynced(session, 1000); + } catch (InterruptedException | IllegalStateException e) { logger.debug("\nPolicyDBDao.register() caught an IllegalStateException: \n" + e + "\n"); DatabaseLockEntity lock; - lock = em.find(DatabaseLockEntity.class, 1); + lock = (DatabaseLockEntity) session.get(DatabaseLockEntity.class, 1); if (lock == null) { lock = new DatabaseLockEntity(); - em.persist(lock); lock.setKey(1); try { - em.flush(); - em.getTransaction().commit(); - em.close(); + session.persist(lock); + session.flush(); + session.getTransaction().commit(); + session.close(); } catch (Exception e2) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR, "COULD NOT CREATE DATABASELOCK ROW. WILL TRY ONE MORE TIME"); } - em = emf.createEntityManager(); + session = sessionfactory.openSession(); try { - startTransactionSynced(em, 1000); + startTransactionSynced(session, 1000); } catch (Exception e3) { String msg = "DATABASE LOCKING NOT WORKING. CONCURRENCY CONTROL NOT WORKING"; - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, policyDBDaoVar, msg); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e3, POLICYDBDAO_VAR, msg); throw new IllegalStateException("msg" + "\n" + e3); } } } logger.debug("\nPolicyDBDao.register. Database locking and concurrency control is initialized\n"); - PolicyDBDaoEntity foundPolicyDBDaoEntity = em.find(PolicyDBDaoEntity.class, url[0]); - Query getPolicyDBDaoEntityQuery = - em.createQuery("SELECT e FROM PolicyDBDaoEntity e WHERE e.policyDBDaoUrl=:url"); - getPolicyDBDaoEntityQuery.setParameter("url", url[0]); + PolicyDBDaoEntity foundPolicyDBDaoEntity = null; + Criteria cr = session.createCriteria(PolicyDBDaoEntity.class); + cr.add(Restrictions.eq("policyDBDaoUrl", url[0])); + List<?> data = cr.list(); + if (!data.isEmpty()) { + foundPolicyDBDaoEntity = (PolicyDBDaoEntity) data.get(0); + } + // encrypt the password String txt = null; try { txt = CryptoUtils.encryptTxt(url[2].getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { logger.debug(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Could not encrypt PAP password"); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Could not encrypt PAP password"); } if (foundPolicyDBDaoEntity == null) { PolicyDBDaoEntity newPolicyDBDaoEntity = new PolicyDBDaoEntity(); - em.persist(newPolicyDBDaoEntity); newPolicyDBDaoEntity.setPolicyDBDaoUrl(url[0]); newPolicyDBDaoEntity.setDescription("PAP server at " + url[0]); newPolicyDBDaoEntity.setUsername(url[1]); newPolicyDBDaoEntity.setPassword(txt); try { - em.getTransaction().commit(); + session.persist(newPolicyDBDaoEntity); + session.getTransaction().commit(); } catch (Exception e) { logger.debug(e); try { - em.getTransaction().rollback(); + session.getTransaction().rollback(); } catch (Exception e2) { logger.debug(e2); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR, "Could not add new PolicyDBDao to the database"); } } @@ -420,453 +387,28 @@ public class PolicyDBDao { } foundPolicyDBDaoEntity.preUpdate(); try { - em.getTransaction().commit(); + session.getTransaction().commit(); } catch (Exception e) { logger.debug(e); try { - em.getTransaction().rollback(); + session.getTransaction().rollback(); } catch (Exception e2) { logger.debug(e2); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR, "Could not update PolicyDBDao in the database"); } } } - em.close(); + session.close(); logger.debug("\nPolicyDBDao.register(). Success!!\n"); return true; } - private class NotifyOtherThread implements Runnable { - public NotifyOtherThread(Object obj, long entityId, String entityType, String newGroupId) { - this.obj = obj; - this.entityId = entityId; - this.entityType = entityType; - this.newGroupId = newGroupId; - } - - private Object obj; - private long entityId; - private String entityType; - private String newGroupId; - - @Override - public void run() { - // naming of 'o' is for backwards compatibility with the rest of the function - PolicyDBDaoEntity dbdEntity = (PolicyDBDaoEntity) obj; - String o = dbdEntity.getPolicyDBDaoUrl(); - String username = dbdEntity.getUsername(); - String txt; - try { - txt = new String(CryptoUtils.decryptTxt(dbdEntity.getPassword()), StandardCharsets.UTF_8); - } catch (Exception e) { - logger.debug(e); - // if we can't decrypt, might as well try it anyway - txt = dbdEntity.getPassword(); - } - Base64.Encoder encoder = Base64.getEncoder(); - String encoding = encoder.encodeToString((username + ":" + txt).getBytes(StandardCharsets.UTF_8)); - HttpURLConnection connection = null; - UUID requestID = UUID.randomUUID(); - URL url; - String papUrl; - try { - String[] papUrlUserPass = getPapUrlUserPass(); - if (papUrlUserPass == null) { - papUrl = "undefined"; - } else { - papUrl = papUrlUserPass[0]; - } - logger.debug("We are going to try to notify " + o); - // is this our own url? - String ourUrl = o; - try { - ourUrl = splitPapUrlUserPass((String) o)[0]; - } catch (Exception e) { - logger.debug(e); - } - if (o == null) { - o = "undefined"; - } - if (papUrl.equals(ourUrl)) { - logger.debug(o + " is our url, skipping notify"); - return; - } - if (newGroupId == null) { - url = new URL( - o + "?policydbdaourl=" + papUrl + "&entityid=" + entityId + "&entitytype=" + entityType); - } else { - url = new URL(o + "?policydbdaourl=" + papUrl + "&entityid=" + entityId + "&entitytype=" - + entityType + "&extradata=" + newGroupId); - } - } catch (MalformedURLException e) { - logger.warn("Caught MalformedURLException on: new URL()", e); - return; - } - // - // Open up the connection - // - logger.info("PolicyDBDao: NotifyOtherThread: notifying other PAPs of an update"); - logger.info("Connecting with url: " + url); - try { - connection = (HttpURLConnection) url.openConnection(); - } catch (Exception e) { - logger.warn("Caught exception on: url.openConnection()", e); - return; - } - // - // Setup our method and headers - // - try { - connection.setRequestMethod("PUT"); - } catch (ProtocolException e) { - // why would this error ever occur? - logger.warn("Caught ProtocolException on connection.setRequestMethod(\"PUT\");", e); - return; - } - connection.setRequestProperty("Authorization", "Basic " + encoding); - connection.setRequestProperty("Accept", "text/x-java-properties"); - connection.setRequestProperty("Content-Type", "text/x-java-properties"); - connection.setRequestProperty("requestID", requestID.toString()); - int readTimeout; - try { - readTimeout = - Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_NOTIFY_TIMEOUT)); - } catch (Exception e) { - logger.error("xacml.rest.pap.notify.timeoutms property not set, using a default.", e); - readTimeout = 10000; - } - connection.setReadTimeout(readTimeout); - connection.setConnectTimeout(readTimeout); - connection.setUseCaches(false); - // - // Adding this in. It seems the HttpUrlConnection class does NOT - // properly forward our headers for POST re-direction. It does so - // for a GET re-direction. - // - // So we need to handle this ourselves. - // - connection.setInstanceFollowRedirects(false); - connection.setDoOutput(true); - connection.setDoInput(true); - try { - connection.connect(); - } catch (Exception e) { - logger.warn("Caught exception on: connection.connect()", e); - return; - } - try { - if (connection.getResponseCode() == 200) { - logger.info("PolicyDBDao: NotifyOtherThread received response 200 from pap server on notify"); - } else { - logger.warn("PolicyDBDao: NotifyOtherThread connection response code not 200, received: " - + connection.getResponseCode()); - } - } catch (Exception e) { - logger.warn("Caught Exception on: connection.getResponseCode() ", e); - } - - connection.disconnect(); - } - } - - private static String evaluateXPath(String expression, String xml) { - InputSource source = new InputSource(new StringReader(xml)); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - String description = ""; - try { - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(source); - - XPathFactory xpathFactory = XPathFactory.newInstance(); - XPath xpath = xpathFactory.newXPath(); - - description = xpath.evaluate(expression, document); - } catch (Exception e) { - logger.error("Exception Occured while evaluating path" + e); - } - return description; - } - - private static final String POLICY_NOTIFICATION = "policy"; - private static final String PDP_NOTIFICATION = "pdp"; - private static final String GROUP_NOTIFICATION = "group"; - - public void handleIncomingHttpNotification(String url, String entityId, String entityType, String extraData, - XACMLPapServlet xacmlPapServlet) { - logger.info("DBDao url: " + url + " has reported an update on " + entityType + " entity " + entityId); - PolicyDBDaoTransaction transaction = this.getNewTransaction(); - // although its named retries, this is the total number of tries - int retries; - try { - retries = Integer - .parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_INCOMINGNOTIFICATION_TRIES)); - } catch (Exception e) { - logger.error("xacml.rest.pap.incomingnotification.tries property not set, using a default of 3." + e); - retries = 3; - } - // if someone sets it to some dumb value, we need to make sure it will try at least once - if (retries < 1) { - retries = 1; - } - int pauseBetweenRetries = 1000; - switch (entityType) { - - case POLICY_NOTIFICATION: - for (int i = 0; i < retries; i++) { - try { - handleIncomingPolicyChange(entityId); - break; - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught exception on handleIncomingPolicyChange(" + url + ", " + entityId + ", " - + extraData + ")"); - } - try { - Thread.sleep(pauseBetweenRetries); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - break; - } - } - break; - case PDP_NOTIFICATION: - for (int i = 0; i < retries; i++) { - try { - handleIncomingPdpChange(entityId, transaction); - break; - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught exception on handleIncomingPdpChange(" + url + ", " + entityId + ", " - + transaction + ")"); - } - try { - Thread.sleep(pauseBetweenRetries); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - break; - } - } - break; - case GROUP_NOTIFICATION: - for (int i = 0; i < retries; i++) { - try { - handleIncomingGroupChange(entityId, extraData, transaction); - break; - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught exception on handleIncomingGroupChange(" + url + ", " + entityId + ", " - + extraData + ", " + transaction + ", " + xacmlPapServlet + ")"); - } - try { - Thread.sleep(pauseBetweenRetries); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - break; - } - } - break; - } - // no changes should be being made in this function, we still need to close - transaction.rollbackTransaction(); - } - - private void handleIncomingGroupChange(String groupId, String extraData, PolicyDBDaoTransaction transaction) - throws PAPException, PolicyDBException { - GroupEntity groupRecord = null; - long groupIdLong = -1; - try { - groupIdLong = Long.parseLong(groupId); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("groupId " + groupId + " cannot be parsed into a long"); - } - try { - groupRecord = transaction.getGroup(groupIdLong); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get pdp group record with transaction.getGroup(" + groupIdLong + ");"); - throw new PAPException("Could not get local group " + groupIdLong); - } - if (groupRecord == null) { - throw new PersistenceException("The group record returned is null"); - } - // compare to local fs - // does group folder exist - OnapPDPGroup localGroup = null; - try { - localGroup = papEngine.getGroup(groupRecord.getGroupId()); - } catch (Exception e) { - logger.warn("Caught PAPException trying to get local pdp group with papEngine.getGroup(" + groupId + ");", - e); - } - if (localGroup == null && extraData != null) { - // here we can try to load an old group id from the extraData - try { - localGroup = papEngine.getGroup(extraData); - } catch (Exception e) { - logger.warn( - "Caught PAPException trying to get local pdp group with papEngine.getGroup(" + extraData + ");", - e); - } - } - if (localGroup != null && groupRecord.isDeleted()) { - OnapPDPGroup newLocalGroup = null; - if (extraData != null) { - try { - newLocalGroup = papEngine.getGroup(extraData); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to get new pdp group with papEngine.getGroup(" + extraData - + ");"); - } - } - try { - papEngine.removeGroup(localGroup, newLocalGroup); - } catch (NullPointerException | PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to get remove pdp group with papEngine.removeGroup(" + localGroup - + ", " + newLocalGroup + ");"); - throw new PAPException("Could not remove group " + groupId); - } - } else if (localGroup == null) { - // creating a new group - try { - papEngine.newGroup(groupRecord.getgroupName(), groupRecord.getDescription()); - } catch (NullPointerException | PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to create pdp group with papEngine.newGroup(groupRecord" - + ".getgroupName(), groupRecord.getDescription());"); - throw new PAPException("Could not create group " + groupRecord); - } - try { - localGroup = papEngine.getGroup(groupRecord.getGroupId()); - } catch (PAPException e1) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, - "Caught PAPException trying to get pdp group we just created with papEngine.getGroup" - + "(groupRecord.getGroupId());\nAny PDPs or policies in the new group may not have been added"); - return; - } - // add possible pdps to group - List<?> pdpsInGroup = transaction.getPdpsInGroup(Long.parseLong(groupRecord.getGroupId())); - for (Object pdpO : pdpsInGroup) { - PdpEntity pdp = (PdpEntity) pdpO; - try { - papEngine.newPDP(pdp.getPdpId(), localGroup, pdp.getPdpName(), pdp.getDescription(), - pdp.getJmxPort()); - } catch (NullPointerException | PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to get create pdp with papEngine.newPDP(pdp.getPdpId(), " - + "localGroup, pdp.getPdpName(), pdp.getDescription(), pdp.getJmxPort());"); - throw new PAPException("Could not create pdp " + pdp); - } - } - // add possible policies to group (filesystem only, apparently) - } else { - if (!(localGroup instanceof StdPDPGroup)) { - throw new PAPException("group is not a StdPDPGroup"); - } - // clone the object - // because it will be comparing the new group to its own version - StdPDPGroup localGroupClone = new StdPDPGroup(localGroup.getId(), localGroup.isDefaultGroup(), - localGroup.getName(), localGroup.getDescription(), ((StdPDPGroup) localGroup).getDirectory()); - localGroupClone.setOnapPdps(localGroup.getOnapPdps()); - localGroupClone.setPipConfigs(localGroup.getPipConfigs()); - localGroupClone.setStatus(localGroup.getStatus()); - // we are updating a group or adding a policy or changing default - // set default if it should be - if (!localGroupClone.isDefaultGroup() && groupRecord.isDefaultGroup()) { - try { - papEngine.setDefaultGroup(localGroup); - return; - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to set default group with papEngine.SetDefaultGroup(" - + localGroupClone + ");"); - throw new PAPException("Could not set default group to " + localGroupClone); - } - } - boolean needToUpdate = false; - if (updateGroupPoliciesInFileSystem(localGroupClone, localGroup, groupRecord)) { - needToUpdate = true; - } - if (!stringEquals(localGroupClone.getId(), groupRecord.getGroupId()) - || !stringEquals(localGroupClone.getName(), groupRecord.getgroupName())) { - // changing ids - // we do not want to change the id, the papEngine will do this for us, it needs to know the old id - localGroupClone.setName(groupRecord.getgroupName()); - needToUpdate = true; - } - if (!stringEquals(localGroupClone.getDescription(), groupRecord.getDescription())) { - localGroupClone.setDescription(groupRecord.getDescription()); - needToUpdate = true; - } - if (needToUpdate) { - try { - papEngine.updateGroup(localGroupClone); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to update group with papEngine.updateGroup(" + localGroupClone - + ");"); - throw new PAPException("Could not update group " + localGroupClone); - } - } - } - } - - // this will also handle removes, since incoming pdpGroup has no policies internally, we are just going to add - // them all in from the db - private boolean updateGroupPoliciesInFileSystem(OnapPDPGroup pdpGroup, OnapPDPGroup oldPdpGroup, - GroupEntity groupRecord) throws PAPException, PolicyDBException { - if (!(pdpGroup instanceof StdPDPGroup)) { - throw new PAPException("group is not a StdPDPGroup"); - } - StdPDPGroup group = (StdPDPGroup) pdpGroup; - // this must always be true since we don't explicitly know when a delete is occuring - boolean didUpdate = true; - HashMap<String, PDPPolicy> currentPolicySet = new HashMap<>(oldPdpGroup.getPolicies().size()); - HashSet<PDPPolicy> newPolicySet = new HashSet<>(); - for (PDPPolicy pdpPolicy : oldPdpGroup.getPolicies()) { - currentPolicySet.put(pdpPolicy.getId(), pdpPolicy); - } - for (PolicyEntity policy : groupRecord.getPolicies()) { - String pdpPolicyName = getPdpPolicyName(policy.getPolicyName(), policy.getScope()); - if (group.getPolicy(pdpPolicyName) == null) { - didUpdate = true; - if (currentPolicySet.containsKey(pdpPolicyName)) { - newPolicySet.add(currentPolicySet.get(pdpPolicyName)); - } else { - logger.info( - "PolicyDBDao: Adding the new policy to the PDP group after notification: " + pdpPolicyName); - InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); - group.copyPolicyToFile(pdpPolicyName, policyStream); - ((StdPDPPolicy) (group.getPolicy(pdpPolicyName))) - .setName(removeExtensionAndVersionFromPolicyName(pdpPolicyName)); - try { - policyStream.close(); - } catch (IOException e) { - didUpdate = false; - PolicyLogger.error(e.getMessage() + e); - } - } - } - } - logger.info("PolicyDBDao: Adding updated policies to group after notification."); - if (didUpdate) { - newPolicySet.addAll(group.getPolicies()); - group.setPolicies(newPolicySet); - } - return didUpdate; - } - /* - * This method is called during all pushPolicy transactions and makes sure the file system group is in sync with the - * database groupentity + * This method is called during all pushPolicy transactions and makes sure the file system group + * is in sync with the database groupentity */ - private StdPDPGroup synchronizeGroupPoliciesInFileSystem(StdPDPGroup pdpGroup, GroupEntity groupentity) + public StdPDPGroup synchronizeGroupPoliciesInFileSystem(StdPDPGroup pdpGroup, GroupEntity groupentity) throws PAPException, PolicyDBException { HashMap<String, PDPPolicy> currentPolicyMap = new HashMap<>(); @@ -895,6 +437,7 @@ public class PolicyDBDao { newPolicy = new StdPDPPolicy(pdpPolicyId, true, removeExtensionAndVersionFromPolicyName(pdpPolicyId), location); newPolicySet.add(newPolicy); + logger.info("Adding new policy to PDPGroup - " + newPolicy.getId() + ", Location - " + location); } catch (Exception e) { logger.debug(e); PolicyLogger @@ -911,8 +454,8 @@ public class PolicyDBDao { } catch (Exception e) { logger.debug(e); PolicyLogger - .error("PolicyDBDao: Exception occurred while attempting to delete the old version of the" - + " policy file from the group. " + e.getMessage()); + .error("PolicyDBDao: Exception occurred while attempting to delete the old version of the policy file from the group. " + + e.getMessage()); } } } @@ -923,7 +466,7 @@ public class PolicyDBDao { return pdpGroup; } - private String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException { + public String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException { return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0]; } @@ -933,7 +476,7 @@ public class PolicyDBDao { * @param originalPolicyName: a policy file name ex: Config_policy.2.xml * @return An array [0]: The policy name, [1]: the policy version, as a string */ - private String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException { + public String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException { String policyName = originalPolicyName; String[] nameAndVersion = new String[2]; try { @@ -958,160 +501,7 @@ public class PolicyDBDao { return nameAndVersion; } - private void handleIncomingPdpChange(String pdpId, PolicyDBDaoTransaction transaction) throws PAPException { - // get pdp - long pdpIdLong = -1; - try { - pdpIdLong = Long.parseLong(pdpId); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("pdpId " + pdpId + " cannot be parsed into a long"); - } - PdpEntity pdpRecord = null; - try { - pdpRecord = transaction.getPdp(pdpIdLong); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get pdp record with transaction.getPdp(" + pdpIdLong + ");"); - throw new PAPException("Could not get local pdp " + pdpIdLong); - } - if (pdpRecord == null) { - throw new PersistenceException("The pdpRecord returned is null"); - } - PDP localPdp = null; - try { - localPdp = papEngine.getPDP(pdpRecord.getPdpId()); - } catch (PAPException e) { - logger.warn("Caught PAPException trying to get local pdp with papEngine.getPDP(" + pdpId + ");", e); - } - if (localPdp != null && pdpRecord.isDeleted()) { - try { - papEngine.removePDP((OnapPDP) localPdp); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to get remove pdp with papEngine.removePDP(" + localPdp + ");"); - throw new PAPException("Could not remove pdp " + pdpId); - } - } else if (localPdp == null) { - // add new pdp - // get group - OnapPDPGroup localGroup = null; - try { - localGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId()); - } catch (PAPException e1) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, - "Caught PAPException trying to get local group to add pdp to with papEngine.getGroup" - + "(pdpRecord.getGroup().getGroupId());"); - throw new PAPException("Could not get local group"); - } - try { - papEngine.newPDP(pdpRecord.getPdpId(), localGroup, pdpRecord.getPdpName(), pdpRecord.getDescription(), - pdpRecord.getJmxPort()); - } catch (NullPointerException | PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to create pdp with papEngine.newPDP(" + pdpRecord.getPdpId() + ", " - + localGroup + ", " + pdpRecord.getPdpName() + ", " + pdpRecord.getDescription() + ", " - + pdpRecord.getJmxPort() + ");"); - throw new PAPException("Could not create pdp " + pdpRecord); - } - } else { - boolean needToUpdate = false; - if (!stringEquals(localPdp.getId(), pdpRecord.getPdpId()) - || !stringEquals(localPdp.getName(), pdpRecord.getPdpName())) { - // again, we don't want to change the id, the papEngine will do this - localPdp.setName(pdpRecord.getPdpName()); - needToUpdate = true; - } - if (!stringEquals(localPdp.getDescription(), pdpRecord.getDescription())) { - localPdp.setDescription(pdpRecord.getDescription()); - needToUpdate = true; - } - String localPdpGroupId = null; - try { - localPdpGroupId = papEngine.getPDPGroup((OnapPDP) localPdp).getId(); - } catch (PAPException e) { - // could be null or something, just warn at this point - logger.warn("Caught PAPException trying to get id of local group that pdp is in with localPdpGroupId = " - + "papEngine.getPDPGroup(localPdp).getId();", e); - } - if (!stringEquals(localPdpGroupId, pdpRecord.getGroup().getGroupId())) { - OnapPDPGroup newPdpGroup = null; - try { - newPdpGroup = papEngine.getGroup(pdpRecord.getGroup().getGroupId()); - } catch (PAPException e) { - // ok, now we have an issue. Time to stop things - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to get id of local group to move pdp to with papEngine" - + ".getGroup(pdpRecord.getGroup().getGroupId());"); - throw new PAPException("Could not get local group"); - } - try { - papEngine.movePDP((OnapPDP) localPdp, newPdpGroup); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to move pdp with papEngine.movePDP(localPdp, newPdpGroup);"); - throw new PAPException("Could not move pdp " + localPdp); - } - } - if (((PdpEntity) localPdp).getJmxPort() != pdpRecord.getJmxPort()) { - ((PdpEntity) localPdp).setJmxPort(pdpRecord.getJmxPort()); - needToUpdate = true; - } - if (needToUpdate) { - try { - papEngine.updatePDP((OnapPDP) localPdp); - } catch (PAPException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PAPException trying to update pdp with papEngine.updatePdp(" + localPdp + ");"); - throw new PAPException("Could not update pdp " + localPdp); - } - } - } - // compare to local situation - // call command to update - } - - private void handleIncomingPolicyChange(String policyId) { - String policyName = null; - EntityManager em = emf.createEntityManager(); - Query getPolicyEntityQuery = em.createNamedQuery("PolicyEntity.FindById"); - getPolicyEntityQuery.setParameter("id", Long.valueOf(policyId)); - - @SuppressWarnings("unchecked") - List<PolicyEntity> policies = getPolicyEntityQuery.getResultList(); - PolicyEntity policy = null; - if (!policies.isEmpty()) { - policy = policies.get(0); - } - String action = "unknown action"; - try { - if (policy != null) { - policyName = policy.getPolicyName(); - logger.info("Deleting old Policy Config File for " + policy.getPolicyName()); - action = "delete"; - Path subFile = null; - - if (policy.getConfigurationData() != null) { - subFile = getPolicySubFile(policy.getConfigurationData().getConfigurationName(), config); - } else if (policy.getActionBodyEntity() != null) { - subFile = getPolicySubFile(policy.getActionBodyEntity().getActionBodyName(), action); - } - - if (subFile != null) { - Files.deleteIfExists(subFile); - } - if (policy.getConfigurationData() != null) { - writePolicySubFile(policy, config); - } else if (policy.getActionBodyEntity() != null) { - writePolicySubFile(policy, action); - } - } - } catch (IOException e1) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, - "Error occurred while performing [" + action + "] of Policy File: " + policyName); - } - } - - private String getPdpPolicyName(String name, String scope) { + public String getPdpPolicyName(String name, String scope) { String finalName = ""; finalName += scope; finalName += "."; @@ -1124,109 +514,29 @@ public class PolicyDBDao { return fileName.substring(0, fileName.lastIndexOf('.')); } - private Path getPolicySubFile(String inputFileName, String subFileType) { - String filename = inputFileName; - logger.info("getPolicySubFile(" + filename + ", " + subFileType + ")"); - Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS), subFileType); - File file = null; - - filename = FilenameUtils.removeExtension(filename); - - for (File tmpFile : filePath.toFile().listFiles()) { - if (FilenameUtils.removeExtension(tmpFile.getName()).equals(filename)) { - file = tmpFile; - } - } - - Path finalPath = null; - if (file != null) { - finalPath = Paths.get(file.getAbsolutePath()); - } - - logger.info("end of getPolicySubFile: " + finalPath); - return finalPath; - } - - private boolean writePolicySubFile(PolicyEntity policy, String policyType) { - logger.info("writePolicySubFile with policyName[" + policy.getPolicyName() + "] and policyType[" + policyType - + "]"); - String type = null; - String subTypeName = null; - String subTypeBody = null; - if (config.equalsIgnoreCase(policyType)) { - type = config; - subTypeName = FilenameUtils.removeExtension(policy.getConfigurationData().getConfigurationName()); - subTypeBody = policy.getConfigurationData().getConfigBody(); - - String configType = policy.getConfigurationData().getConfigType(); - - if (configType != null) { - if (configType.equals(JSON_CONFIG)) { - subTypeName = subTypeName + ".json"; - } - if (configType.equals(XML_CONFIG)) { - subTypeName = subTypeName + ".xml"; - } - if (configType.equals(PROPERTIES_CONFIG)) { - subTypeName = subTypeName + ".properties"; - } - if (configType.equals(OTHER_CONFIG)) { - subTypeName = subTypeName + ".txt"; - } - } - } else if (action.equalsIgnoreCase(policyType)) { - type = action; - subTypeName = policy.getActionBodyEntity().getActionBodyName(); - subTypeBody = policy.getActionBodyEntity().getActionBody(); - } - Path filePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS).toString(), type); - - if (subTypeBody == null) { - subTypeBody = ""; - } - boolean success = false; - try { - Files.deleteIfExists(Paths.get(filePath.toString(), subTypeName)); - File file = Paths.get(filePath.toString(), subTypeName).toFile(); - boolean value = file.createNewFile(); - logger.debug("New file created successfully" + value); - try (FileWriter fileWriter = new FileWriter(file, false)) { - // false to overwrite - fileWriter.write(subTypeBody); - fileWriter.close(); - success = true; - } - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Exception occured while creating Configuration File for Policy : " + policy.getPolicyName()); - } - return success; - } - public void auditLocalDatabase(PAPPolicyEngine papEngine2) { logger.debug("PolicyDBDao.auditLocalDatabase() is called"); try { deleteAllGroupTables(); auditGroups(papEngine2); } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "auditLocalDatabase() error"); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "auditLocalDatabase() error"); logger.error("Exception Occured" + e); } } - public StdPDPGroup auditLocalFileSystem(StdPDPGroup group) { logger.info("Starting Local File System group audit"); - EntityManager em = emf.createEntityManager(); - em.getTransaction().begin(); + Session session = sessionfactory.openSession(); + session.getTransaction().begin(); StdPDPGroup updatedGroup = null; try { - Query groupQuery = em.createQuery(groupEntitySelectQuery); - groupQuery.setParameter(groupIdVar, group.getId()); - groupQuery.setParameter(deletedVar, false); - List<?> groupQueryList = groupQuery.getResultList(); + Query groupQuery = session.createQuery(GROUPENTITY_SELECT); + groupQuery.setParameter(GROUP_ID, group.getId()); + groupQuery.setParameter(DELETED, false); + List<?> groupQueryList = groupQuery.list(); if (groupQueryList != null && !groupQueryList.isEmpty()) { GroupEntity dbgroup = (GroupEntity) groupQueryList.get(0); updatedGroup = synchronizeGroupPoliciesInFileSystem(group, dbgroup); @@ -1236,39 +546,91 @@ public class PolicyDBDao { logger.error(e); } catch (Exception e) { logger.error(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Caught Exception trying to check if group exists groupQuery.getResultList()"); throw new PersistenceException("Query failed trying to check if group " + group.getId() + " exists"); } - em.getTransaction().commit(); - em.close(); + session.getTransaction().commit(); + session.close(); return updatedGroup; + } + + /* + * This method is called at startup to recreate config data from DB to the file system. + * + */ + public void synchronizeConfigDataInFileSystem() { + logger.info("Starting Local File System Config data Sync"); + // sync both web apps Config and Action + syncConfigData(ConfigurationDataEntity.class, CONFIG); + syncConfigData(ActionBodyEntity.class, ACTION); + } + + private <T> void syncConfigData(Class<T> cl, String type) { + Session session = sessionfactory.openSession(); + try { + final Criteria configDataQuery = session.createCriteria(cl.getName()); + @SuppressWarnings("unchecked") + final List<T> configDataResult = configDataQuery.list(); + Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS), type); + + for (final T configData : configDataResult) { + String configName = null; + byte[] configBody; + try { + if (CONFIG.equalsIgnoreCase(type)) { + configName = ((ConfigurationDataEntity) configData).getConfigurationName(); + configBody = (((ConfigurationDataEntity) configData).getConfigBody() != null) + ? ((ConfigurationDataEntity) configData).getConfigBody() + .getBytes(StandardCharsets.UTF_8) + : "".getBytes(); + } else { + configName = ((ActionBodyEntity) configData).getActionBodyName(); + configBody = (((ActionBodyEntity) configData).getActionBody() != null) + ? ((ActionBodyEntity) configData).getActionBody().getBytes(StandardCharsets.UTF_8) + : "".getBytes(); + } + Path filePath = Paths.get(webappsPath.toString(), configName); + if (!filePath.toFile().exists()) { + Files.write(filePath, configBody); + logger.info("Created Config File from DB - " + filePath.toString()); + } + } catch (Exception e) { + // log and keep going + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, + "Exception occured while creating Configuration File - " + configName); + } + } + } catch (final Exception exception) { + logger.error("Unable to synchronizeConfigDataInFileSystem", exception); + } + session.close(); } public void deleteAllGroupTables() { logger.debug("PolicyDBDao.deleteAllGroupTables() called"); - EntityManager em = emf.createEntityManager(); - em.getTransaction().begin(); + Session session = sessionfactory.openSession(); + session.getTransaction().begin(); - Query deletePdpEntityEntityTableUpdate = em.createNamedQuery("PdpEntity.deleteAll"); + Query deletePdpEntityEntityTableUpdate = session.getNamedQuery("PdpEntity.deleteAll"); deletePdpEntityEntityTableUpdate.executeUpdate(); - Query deleteGroupEntityTableUpdate = em.createNamedQuery("GroupEntity.deleteAll"); + Query deleteGroupEntityTableUpdate = session.getNamedQuery("GroupEntity.deleteAll"); deleteGroupEntityTableUpdate.executeUpdate(); - em.getTransaction().commit(); - em.close(); + session.getTransaction().commit(); + session.close(); } @SuppressWarnings("unchecked") public void auditGroups(PAPPolicyEngine papEngine2) { logger.debug("PolicyDBDao.auditGroups() called"); - EntityManager em = emf.createEntityManager(); - em.getTransaction().begin(); + Session session = sessionfactory.openSession(); + session.getTransaction().begin(); final String AUDIT_STR = "Audit"; try { @@ -1277,25 +639,24 @@ public class PolicyDBDao { for (OnapPDPGroup grp : groups) { try { GroupEntity groupEntity = new GroupEntity(); - em.persist(groupEntity); groupEntity.setGroupName(grp.getName()); groupEntity.setDescription(grp.getDescription()); groupEntity.setDefaultGroup(grp.isDefaultGroup()); groupEntity.setCreatedBy(AUDIT_STR); groupEntity.setGroupId(createNewPDPGroupId(grp.getId())); groupEntity.setModifiedBy(AUDIT_STR); + session.persist(groupEntity); Set<OnapPDP> pdps = grp.getOnapPdps(); for (OnapPDP pdp : pdps) { PdpEntity pdpEntity = new PdpEntity(); - em.persist(pdpEntity); pdpEntity.setGroup(groupEntity); pdpEntity.setJmxPort(pdp.getJmxPort()); pdpEntity.setPdpId(pdp.getId()); pdpEntity.setPdpName(pdp.getName()); pdpEntity.setModifiedBy(AUDIT_STR); pdpEntity.setCreatedBy(AUDIT_STR); - + session.persist(pdpEntity); } Set<PDPPolicy> policies = grp.getPolicies(); @@ -1308,11 +669,11 @@ public class PolicyDBDao { "Invalid input - policyID must contain name, scope and version"); } List<PolicyEntity> policyEntityList; - Query getPolicyEntitiesQuery = em.createNamedQuery("PolicyEntity.findByNameAndScope"); + Query getPolicyEntitiesQuery = session.getNamedQuery("PolicyEntity.findByNameAndScope"); getPolicyEntitiesQuery.setParameter("name", stringArray[0]); - getPolicyEntitiesQuery.setParameter(scope, stringArray[1]); + getPolicyEntitiesQuery.setParameter(SCOPE, stringArray[1]); - policyEntityList = getPolicyEntitiesQuery.getResultList(); + policyEntityList = getPolicyEntitiesQuery.list(); PolicyEntity policyEntity = null; if (!policyEntityList.isEmpty()) { policyEntity = policyEntityList.get(0); @@ -1321,28 +682,28 @@ public class PolicyDBDao { groupEntity.addPolicyToGroup(policyEntity); } } catch (Exception e2) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e2, POLICYDBDAO_VAR, "Exception auditGroups inner catch"); } } } catch (Exception e1) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, POLICYDBDAO_VAR, "Exception auditGroups middle catch"); } } } catch (Exception e) { - em.getTransaction().rollback(); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, "Exception auditGroups outer catch"); - em.close(); + session.getTransaction().rollback(); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, POLICYDBDAO_VAR, "Exception auditGroups outer catch"); + session.close(); return; } - em.getTransaction().commit(); - em.close(); + session.getTransaction().commit(); + session.close(); } - private String getConfigFile(String filename, PolicyRestAdapter policy) { + public String getConfigFile(String filename, PolicyRestAdapter policy) { if (policy == null) { return getConfigFile(filename, (String) null); } @@ -1352,7 +713,7 @@ public class PolicyDBDao { // copied from ConfigPolicy.java and modified // Here we are adding the extension for the configurations file based on the // config type selection for saving. - private String getConfigFile(String inputFilename, String configType) { + public String getConfigFile(String inputFilename, String configType) { String filename = inputFilename; logger.debug("getConfigFile(String filename, String scope, String configType) as getConfigFile(" + filename + ", " + configType + ") called"); @@ -1376,7 +737,7 @@ public class PolicyDBDao { return filename; } - private String[] getNameScopeAndVersionFromPdpPolicy(String fileName) { + public String[] getNameScopeAndVersionFromPdpPolicy(String fileName) { String[] splitByDots = fileName.split("\\."); if (splitByDots.length < 3) { return null; @@ -1401,7 +762,8 @@ public class PolicyDBDao { public static String createNewPDPGroupId(String name) { String id = name; - // replace "bad" characters with sequences that will be ok for file names and properties keys. + // replace "bad" characters with sequences that will be ok for file + // names and properties keys. id = id.replace(" ", "_sp_"); id = id.replace("\t", "_tab_"); id = id.replace("\\", "_bksl_"); @@ -1435,1429 +797,6 @@ public class PolicyDBDao { return false; } - - private class PolicyDBDaoTransactionInstance implements PolicyDBDaoTransaction { - private EntityManager em; - private final Object emLock = new Object(); - long policyId; - long groupId; - long pdpId; - String newGroupId; - private boolean operationRun = false; - private final Thread transactionTimer; - - private PolicyDBDaoTransactionInstance() { - // call the constructor with arguments - this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)), - Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT))); - } - - // timeout is how long the transaction can sit before rolling back - // wait time is how long to wait for the transaction to start before throwing an exception - private PolicyDBDaoTransactionInstance(int transactionTimeout, int transactionWaitTime) { - if (logger.isDebugEnabled()) { - logger.debug("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:" - + "\n transactionTimeout = " + transactionTimeout + "\n transactionWaitTime = " - + transactionWaitTime + "\n\n"); - } - this.em = emf.createEntityManager(); - policyId = -1; - groupId = -1; - pdpId = -1; - newGroupId = null; - synchronized (emLock) { - try { - startTransactionSynced(this.em, transactionWaitTime); - } catch (Exception e) { - logger.debug(e); - throw new PersistenceException( - "Could not lock transaction within " + transactionWaitTime + " milliseconds"); - } - } - class TransactionTimer implements Runnable { - - private int sleepTime; - - public TransactionTimer(int timeout) { - this.sleepTime = timeout; - } - - @Override - public void run() { - if (logger.isDebugEnabled()) { - Date date = new java.util.Date(); - logger.debug("\n\nTransactionTimer.run() - SLEEPING: " + "\n sleepTime (ms) = " + sleepTime - + TIMESTAMP + date.getTime() + "\n\n"); - } - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - // probably, the transaction was completed, the last thing we want to do is roll back - if (logger.isDebugEnabled()) { - Date date = new java.util.Date(); - logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: " + TIMESTAMP - + date.getTime() + "\n\n"); - } - Thread.currentThread().interrupt(); - return; - } - if (logger.isDebugEnabled()) { - Date date = new java.util.Date(); - logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: " + TIMESTAMP - + date.getTime() + "\n\n"); - } - rollbackTransaction(); - } - - } - - transactionTimer = new Thread(new TransactionTimer(transactionTimeout), "transactionTimerThread"); - transactionTimer.start(); - - - } - - private void checkBeforeOperationRun() { - checkBeforeOperationRun(false); - } - - private void checkBeforeOperationRun(boolean justCheckOpen) { - if (!isTransactionOpen()) { - PolicyLogger.error("There is no transaction currently open"); - throw new IllegalStateException("There is no transaction currently open"); - } - if (operationRun && !justCheckOpen) { - PolicyLogger.error( - "An operation has already been performed and the current transaction should be " + "committed"); - throw new IllegalStateException( - "An operation has already been performed and the current transaction should be committed"); - } - operationRun = true; - } - - @Override - public void commitTransaction() { - synchronized (emLock) { - logger.debug("commitTransaction() as commitTransaction() called"); - if (!isTransactionOpen()) { - logger.warn("There is no open transaction to commit"); - try { - em.close(); - } catch (Exception e) { - logger.error("Exception Occured" + e); - } - return; - } - try { - em.getTransaction().commit(); - } catch (RollbackException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught RollbackException on em.getTransaction().commit()"); - throw new PersistenceException("The commit failed. Message:\n" + e.getMessage()); - } - em.close(); - // need to revisit - if (policyId >= 0) { - if (newGroupId != null) { - try { - notifyOthers(policyId, POLICY_NOTIFICATION, newGroupId); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - CAUGHTEXCEPTIONONNOTIFY + policyId + "," + POLICY_NOTIFICATION + "," - + newGroupId + ")"); - } - } else { - try { - notifyOthers(policyId, POLICY_NOTIFICATION); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - CAUGHTEXCEPTIONONNOTIFY + policyId + "," + POLICY_NOTIFICATION + ")"); - } - } - } - if (groupId >= 0) { - // we don't want commit to fail just because this does - if (newGroupId != null) { - try { - notifyOthers(groupId, GROUP_NOTIFICATION, newGroupId); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - CAUGHTEXCEPTIONONNOTIFY + groupId + "," + GROUP_NOTIFICATION + "," - + newGroupId + ")"); - } - } else { - try { - notifyOthers(groupId, GROUP_NOTIFICATION); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - CAUGHTEXCEPTIONONNOTIFY + groupId + "," + GROUP_NOTIFICATION + ")"); - } - } - } - if (pdpId >= 0) { - // we don't want commit to fail just because this does - try { - notifyOthers(pdpId, PDP_NOTIFICATION); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - CAUGHTEXCEPTIONONNOTIFY + pdpId + "," + PDP_NOTIFICATION + ")"); - } - } - } - if (transactionTimer != null) { - transactionTimer.interrupt(); - } - } - - @Override - public void rollbackTransaction() { - logger.debug("rollbackTransaction() as rollbackTransaction() called"); - synchronized (emLock) { - if (isTransactionOpen()) { - - try { - em.getTransaction().rollback(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Could not rollback transaction"); - } - try { - em.close(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Could not close EntityManager"); - } - - } else { - try { - em.close(); - } catch (Exception e) { - logger.warn("Could not close already closed transaction", e); - } - } - - } - if (transactionTimer != null) { - transactionTimer.interrupt(); - } - } - - private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String inputPolicyName, - String policyDataString) { - String policyName = inputPolicyName; - logger.debug( - "createPolicy(PolicyRestAdapter policy, String username, String policyScope, String policyName, " - + "String policyDataString) as createPolicy(" + policy + ", " + username + ", " - + policyScope + ", " + policyName + ", " + policyDataString + ") called"); - synchronized (emLock) { - checkBeforeOperationRun(); - String configName = policyName; - if (policyName.contains("Config_")) { - policyName = policyName.replace(".Config_", ":Config_"); - } else if (policyName.contains("Action_")) { - policyName = policyName.replace(".Action_", ":Action_"); - } else if (policyName.contains("Decision_")) { - policyName = policyName.replace(".Decision_", ":Decision_"); - } - policyName = policyName.split(":")[1]; - Query createPolicyQuery = em - .createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"); - createPolicyQuery.setParameter(scope, policyScope); - createPolicyQuery.setParameter("policyName", policyName); - List<?> createPolicyQueryList = createPolicyQuery.getResultList(); - PolicyEntity newPolicyEntity; - boolean update; - if (createPolicyQueryList.isEmpty()) { - newPolicyEntity = new PolicyEntity(); - update = false; - } else if (createPolicyQueryList.size() > 1) { - PolicyLogger - .error("Somehow, more than one policy with the same scope, name, and deleted status were " - + "found in the database"); - throw new PersistenceException( - "Somehow, more than one policy with the same scope, name, and deleted status were found " - + "in the database"); - } else { - newPolicyEntity = (PolicyEntity) createPolicyQueryList.get(0); - update = true; - } - - ActionBodyEntity newActionBodyEntity = null; - if (policy.getPolicyType().equals(action)) { - boolean abupdate = false; - if (newPolicyEntity.getActionBodyEntity() == null) { - newActionBodyEntity = new ActionBodyEntity(); - } else { - newActionBodyEntity = em.find(ActionBodyEntity.class, - newPolicyEntity.getActionBodyEntity().getActionBodyId()); - abupdate = true; - } - - if (newActionBodyEntity != null) { - if (!abupdate) { - em.persist(newActionBodyEntity); - } - // build the file path - // trim the .xml off the end - String policyNameClean = FilenameUtils.removeExtension(configName); - String actionBodyName = policyNameClean + ".json"; - - // get the action body - String actionBodyString = policy.getActionBody(); - if (actionBodyString == null) { - actionBodyString = "{}"; - } - newActionBodyEntity.setActionBody(actionBodyString); - newActionBodyEntity.setActionBodyName(actionBodyName); - newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()"); - newActionBodyEntity.setDeleted(false); - if (!abupdate) { - newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()"); - } - if (logger.isDebugEnabled()) { - logger.debug("\nPolicyDBDao.createPolicy" + "\n newActionBodyEntity.getActionBody() = " - + newActionBodyEntity.getActionBody() - + "\n newActionBodyEntity.getActionBodyName() = " - + newActionBodyEntity.getActionBodyName() - + "\n newActionBodyEntity.getModifiedBy() = " - + newActionBodyEntity.getModifiedBy() + "\n newActionBodyEntity.getCreatedBy() = " - + newActionBodyEntity.getCreatedBy() + "\n newActionBodyEntity.isDeleted() = " - + newActionBodyEntity.isDeleted() + "\n FLUSHING to DB"); - } - // push the actionBodyEntity to the DB - em.flush(); - } else { - // newActionBodyEntity == null - // We have a actionBody in the policy but we found no actionBody in the DB - String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an " - + "actionBody, but it could not be found in the DB for update." + "\n policyScope = " - + policyScope + "\n policyName = " + policyName + "\n\n"; - PolicyLogger - .error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, but it " - + "could not be found in the DB for update: policyName = " + policyName); - throw new IllegalArgumentException(msg); - } - } - - ConfigurationDataEntity newConfigurationDataEntity; - if (policy.getPolicyType().equals(config)) { - boolean configUpdate; - if (newPolicyEntity.getConfigurationData() == null) { - newConfigurationDataEntity = new ConfigurationDataEntity(); - configUpdate = false; - } else { - newConfigurationDataEntity = em.find(ConfigurationDataEntity.class, - newPolicyEntity.getConfigurationData().getConfigurationDataId()); - configUpdate = true; - } - - if (newConfigurationDataEntity != null) { - if (!configUpdate) { - em.persist(newConfigurationDataEntity); - } - if (!stringEquals(newConfigurationDataEntity.getConfigurationName(), - getConfigFile(configName, policy))) { - newConfigurationDataEntity.setConfigurationName(getConfigFile(configName, policy)); - } - if (newConfigurationDataEntity.getConfigType() == null - || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())) { - newConfigurationDataEntity.setConfigType(policy.getConfigType()); - } - if (!configUpdate) { - newConfigurationDataEntity.setCreatedBy(username); - } - if (newConfigurationDataEntity.getModifiedBy() == null - || !newConfigurationDataEntity.getModifiedBy().equals(username)) { - newConfigurationDataEntity.setModifiedBy(username); - } - if (newConfigurationDataEntity.getDescription() == null - || !"".equals(newConfigurationDataEntity.getDescription())) { - newConfigurationDataEntity.setDescription(""); - } - if (newConfigurationDataEntity.getConfigBody() == null - || newConfigurationDataEntity.getConfigBody().isEmpty() - || (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))) { - // hopefully one of these won't be null - if (policy.getConfigBodyData() == null || policy.getConfigBodyData().isEmpty()) { - newConfigurationDataEntity.setConfigBody(policy.getJsonBody()); - } else { - newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData()); - } - } - if (newConfigurationDataEntity.isDeleted()) { - newConfigurationDataEntity.setDeleted(false); - } - - em.flush(); - } else { - // We have a configurationData body in the policy but we found no configurationData body in - // the DB - String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a " - + "configurationData body, but it could not be found in the DB for update." - + "\n policyScope = " + policyScope + "\n policyName = " + policyName + "\n\n"; - PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData " - + "body, but it could not be found in the DB for update: policyName = " + policyName); - throw new IllegalArgumentException(msg); - } - - } else { - newConfigurationDataEntity = null; - } - if (!update) { - em.persist(newPolicyEntity); - } - - policyId = newPolicyEntity.getPolicyId(); - - if (!stringEquals(newPolicyEntity.getPolicyName(), policyName)) { - newPolicyEntity.setPolicyName(policyName); - } - if (!stringEquals(newPolicyEntity.getCreatedBy(), username)) { - newPolicyEntity.setCreatedBy(username); - } - if (!stringEquals(newPolicyEntity.getDescription(), policy.getPolicyDescription())) { - newPolicyEntity.setDescription(policy.getPolicyDescription()); - } - if (!stringEquals(newPolicyEntity.getModifiedBy(), username)) { - newPolicyEntity.setModifiedBy(username); - } - if (!stringEquals(newPolicyEntity.getPolicyData(), policyDataString)) { - newPolicyEntity.setPolicyData(policyDataString); - } - if (!stringEquals(newPolicyEntity.getScope(), policyScope)) { - newPolicyEntity.setScope(policyScope); - } - if (newPolicyEntity.isDeleted() == true) { - newPolicyEntity.setDeleted(false); - } - newPolicyEntity.setConfigurationData(newConfigurationDataEntity); - newPolicyEntity.setActionBodyEntity(newActionBodyEntity); - - em.flush(); - this.policyId = newPolicyEntity.getPolicyId(); - } - } - - @SuppressWarnings("unused") - public PolicyEntity getPolicy(int policyID) { - return getPolicy(policyID, null, null); - } - - public PolicyEntity getPolicy(String policyName, String scope) { - return getPolicy(-1, policyName, scope); - } - - private PolicyEntity getPolicy(int policyID, String policyName, String scope) { - logger.debug("getPolicy(int policyId, String policyName) as getPolicy(" + policyID + "," + policyName - + ") called"); - if (policyID < 0 && isNullOrEmpty(policyName, scope)) { - throw new IllegalArgumentException( - "policyID must be at least 0 or policyName must be not null or blank"); - } - - synchronized (emLock) { - checkBeforeOperationRun(true); - // check if group exists - String policyId; - Query policyQuery; - if (!isNullOrEmpty(policyName, scope)) { - policyId = policyName; - policyQuery = - em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope"); - policyQuery.setParameter("name", policyId); - policyQuery.setParameter("scope", scope); - } else { - policyId = String.valueOf(policyID); - policyQuery = em.createNamedQuery("PolicyEntity.FindById"); - policyQuery.setParameter("id", policyId); - } - List<?> policyQueryList; - try { - policyQueryList = policyQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get policy with policyQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get policy " + policyId); - } - if (policyQueryList.isEmpty()) { - PolicyLogger.error("Policy does not exist with id " + policyId); - throw new PersistenceException("Group policy is being added to does not exist with id " + policyId); - } else if (policyQueryList.size() > 1) { - PolicyLogger.error(duplicatePolicyId + policyId + foundInDB); - throw new PersistenceException(duplicatePolicyId + policyId + foundInDB); - } - return (PolicyEntity) policyQueryList.get(0); - } - } - - @Override - public GroupEntity getGroup(long groupKey) { - logger.debug("getGroup(int groupKey) as getGroup(" + groupKey + ") called"); - if (groupKey < 0) { - throw new IllegalArgumentException("groupKey must be at least 0"); - } - synchronized (emLock) { - checkBeforeOperationRun(true); - // check if group exists - Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey"); - groupQuery.setParameter("groupKey", groupKey); - List<?> groupQueryList; - try { - groupQueryList = groupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get group with groupQuery.getResultList()"); - throw new PersistenceException(queryFailedToGetGroup + groupKey); - } - if (groupQueryList.isEmpty()) { - PolicyLogger.error("Group does not exist with groupKey " + groupKey); - throw new PersistenceException("Group does not exist with groupKey " + groupKey); - } else if (groupQueryList.size() > 1) { - PolicyLogger.error("Somehow, more than one group with the groupKey " + groupKey + foundInDB); - throw new PersistenceException( - "Somehow, more than one group with the groupKey " + groupKey + foundInDB); - } - return (GroupEntity) groupQueryList.get(0); - } - } - - @Override - public GroupEntity getGroup(String groupId) { - logger.debug("getGroup(String groupId) as getGroup(" + groupId + ") called"); - if (isNullOrEmpty(groupId)) { - throw new IllegalArgumentException("groupId must not be null or empty"); - } - synchronized (emLock) { - checkBeforeOperationRun(true); - // check if group exists - Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId"); - groupQuery.setParameter(groupIdVar, groupId); - List<?> groupQueryList; - try { - groupQueryList = groupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get group with groupQuery.getResultList()"); - throw new PersistenceException(queryFailedToGetGroup + groupId); - } - if (groupQueryList.isEmpty()) { - PolicyLogger.error("Group does not exist with id " + groupId); - throw new PersistenceException("Group does not exist with id " + groupId); - } else if (groupQueryList.size() > 1) { - PolicyLogger.error(duplicateGroupId + groupId + foundInDB); - throw new PersistenceException(duplicateGroupId + groupId + foundInDB); - } - return (GroupEntity) groupQueryList.get(0); - } - } - - @Override - public List<?> getPdpsInGroup(long groupKey) { - logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup(" + groupKey + ") called"); - if (groupKey < 0) { - throw new IllegalArgumentException("groupId must not be < 0"); - } - synchronized (emLock) { - checkBeforeOperationRun(true); - Query pdpsQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group"); - pdpsQuery.setParameter("group", getGroup(groupKey)); - return pdpsQuery.getResultList(); - } - } - - @Override - public PdpEntity getPdp(long pdpKey) { - logger.debug("getPdp(int pdpKey) as getPdp(" + pdpKey + ") called"); - if (pdpKey < 0) { - throw new IllegalArgumentException("pdpKey must be at least 0"); - } - synchronized (emLock) { - checkBeforeOperationRun(true); - // check if group exists - Query pdpQuery = em.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey"); - pdpQuery.setParameter("pdpKey", pdpKey); - List<?> pdpQueryList; - try { - pdpQueryList = pdpQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get pdp with pdpQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get pdp " + pdpKey); - } - if (pdpQueryList.isEmpty()) { - PolicyLogger.error("Pdp does not exist with pdpKey " + pdpKey); - throw new PersistenceException("Pdp does not exist with pdpKey " + pdpKey); - } else if (pdpQueryList.size() > 1) { - PolicyLogger.error("Somehow, more than one pdp with the pdpKey " + pdpKey + foundInDB); - throw new PersistenceException("Somehow, more than one pdp with the pdpKey " + pdpKey + foundInDB); - } - return (PdpEntity) pdpQueryList.get(0); - } - } - - @Override - public boolean isTransactionOpen() { - logger.debug("isTransactionOpen() as isTransactionOpen() called"); - synchronized (emLock) { - return em.isOpen() && em.getTransaction().isActive(); - } - } - - private String processConfigPath(String inputConfigPath) { - String configPath = inputConfigPath; - String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS); - if (webappsPath == null) { - logger.error("Webapps property does not exist"); - throw new IllegalArgumentException("Webapps property does not exist"); - } - configPath = configPath.replace("$URL", webappsPath); - // make sure the correct slashes are in - try { - configPath = Paths.get(configPath).toString(); - } catch (InvalidPathException e) { - logger.error("Invalid config path: " + configPath, e); - throw new IllegalArgumentException("Invalid config path: " + configPath); - } - return configPath; - } - - private String readConfigFile(String configPath) { - String configDataString = null; - try (InputStream configContentStream = new FileInputStream(configPath);) { - configDataString = IOUtils.toString(configContentStream); - } catch (FileNotFoundException e) { - logger.error("Caught FileNotFoundException on new FileInputStream(" + configPath + ")", e); - throw new IllegalArgumentException("The config file path does not exist"); - } catch (IOException e2) { - logger.error("Caught IOException on newIOUtils.toString(configContentStream)", e2); - throw new IllegalArgumentException("The config file path cannot be read"); - } - if (configDataString == null) { - throw new IllegalArgumentException("The config file path cannot be read"); - } - return configDataString; - } - - @Override - public void createPolicy(Policy policy, String username) { - - try { - logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy(" + policy + "," - + username + ") called"); - String policyScope = policy.policyAdapter.getDomainDir().replace(File.separator, "."); - // Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP - // and this transaction is intercepted up stream. - - String policyDataString = getPolicyDataString(policy); - if (isJunit) { - // Using parentPath object to set policy data. - policyDataString = policy.policyAdapter.getParentPath(); - } - String configPath = ""; - if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(config)) { - configPath = evaluateXPath( - "/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')" - + "]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", - policyDataString); - } else if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(action)) { - configPath = evaluateXPath( - "/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " - + policy.policyAdapter.getActionAttribute() - + ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", - policyDataString); - } - - String prefix = null; - if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(config)) { - - prefix = configPath.substring( - configPath.indexOf(policyScope + ".") + policyScope.concat(".").length(), - configPath.lastIndexOf(policy.policyAdapter.getPolicyName())); - if (isNullOrEmpty(policy.policyAdapter.getConfigBodyData())) { - policy.policyAdapter.setConfigBodyData(getConfigData(configPath)); - } - } else if (action.equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { - prefix = "Action_"; - } else if ("Decision".equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { - prefix = "Decision_"; - } - - if (!(policy.policyAdapter.getData() instanceof PolicyType) - && !(policy.policyAdapter.getData() instanceof PolicySetType)) { - PolicyLogger.error("The data field is not an instance of PolicyType or PolicySetType"); - throw new IllegalArgumentException( - "The data field is not an instance of PolicyType or PolicySetType"); - } - String finalName = policyScope + "." + prefix + policy.policyAdapter.getPolicyName() + "." - + policy.policyAdapter.getHighestVersion() + ".xml"; - if (policy.policyAdapter.getConfigType() == null || "".equals(policy.policyAdapter.getConfigType())) { - // get the config file extension - String ext = ""; - if (configPath != null && !"".equalsIgnoreCase(configPath)) { - ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());; - } - - if (ext.contains("txt")) { - policy.policyAdapter.setConfigType(OTHER_CONFIG); - } else if (ext.contains("json")) { - policy.policyAdapter.setConfigType(JSON_CONFIG); - } else if (ext.contains("xml")) { - policy.policyAdapter.setConfigType(XML_CONFIG); - } else if (ext.contains("properties")) { - policy.policyAdapter.setConfigType(PROPERTIES_CONFIG); - } else { - if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(action)) { - policy.policyAdapter.setConfigType(JSON_CONFIG); - } - } - } - createPolicy(policy.policyAdapter, username, policyScope, finalName, policyDataString); - } catch (Exception e) { - logger.error("Could not create policy for " + policy, e); - throw e; - } - } - - private String getConfigData(String configPath) { - String configData = ""; - try { - configData = getConfigPath(configPath); - } catch (Exception e) { - logger.error("Could not read config body data for " + configPath, e); - } - return configData; - } - - private String getConfigPath(String configPath) { - try { - String newConfigPath = processConfigPath(configPath); - return readConfigFile(newConfigPath); - } catch (IllegalArgumentException e2) { - logger.error("Could not process config path: " + configPath, e2); - } - return ""; - } - - - /** - * @param policy input policy Object. - * @return read the stream and return policy xml data. - */ - private String getPolicyDataString(Policy policy) { - try (InputStream policyXmlStream = - XACMLPolicyWriter.getXmlAsInputStream(policy.getCorrectPolicyDataObject())) { - return IOUtils.toString(policyXmlStream); - } catch (IOException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught IOException on reading Policy Data."); - throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter."); - } - } - - @Override - public void close() { - synchronized (emLock) { - if (em.isOpen()) { - if (em.getTransaction().isActive()) { - em.getTransaction().rollback(); - } - em.close(); - } - if (transactionTimer != null) { - transactionTimer.interrupt(); - } - } - } - - @Override - public void createGroup(String groupId, String groupName, String inputGroupDescription, String username) { - String groupDescription = inputGroupDescription; - logger.debug("deletePolicy(String policyToDeletes) as createGroup(" + groupId + ", " + groupName + ", " - + groupDescription + ") called"); - if (isNullOrEmpty(groupId, groupName, username)) { - throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty"); - } - if (groupDescription == null) { - groupDescription = ""; - } - - synchronized (emLock) { - checkBeforeOperationRun(); - Query checkGroupQuery = em.createQuery(groupEntitySelectQuery); - checkGroupQuery.setParameter(groupIdVar, groupId); - checkGroupQuery.setParameter(deletedVar, false); - List<?> checkGroupQueryList; - try { - checkGroupQueryList = checkGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on checkGroupQuery.getResultList()"); - throw new PersistenceException(queryFailedToCheckExisting); - } - if (!checkGroupQueryList.isEmpty()) { - PolicyLogger.error("The group being added already exists with id " + groupId); - throw new PersistenceException("The group being added already exists with id " + groupId); - } - GroupEntity newGroup = new GroupEntity(); - em.persist(newGroup); - newGroup.setCreatedBy(username); - newGroup.setModifiedBy(username); - newGroup.setGroupName(groupName); - newGroup.setGroupId(groupId); - newGroup.setDescription(groupDescription); - - em.flush(); - this.groupId = newGroup.getGroupKey(); - } - } - - @Override - public void updateGroup(OnapPDPGroup group, String username) { - logger.info( - "PolicyDBDao: updateGroup(PDPGroup group) as updateGroup(" + group + "," + username + ") called"); - if (group == null) { - throw new IllegalArgumentException("PDPGroup group must not be null"); - } - if (isNullOrEmpty(group.getId(), username)) { - throw new IllegalArgumentException("group.getId() and username must not be null or empty"); - } - - synchronized (emLock) { - checkBeforeOperationRun(); - Query getGroupQuery = em.createQuery(groupEntitySelectQuery); - getGroupQuery.setParameter(groupIdVar, group.getId()); - getGroupQuery.setParameter(deletedVar, false); - List<?> getGroupQueryList; - try { - getGroupQueryList = getGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on getGroupQuery.getResultList()"); - throw new PersistenceException(queryFailedToGetGroup + group.getId() + " for editing"); - } - if (getGroupQueryList.isEmpty()) { - PolicyLogger.error("The group cannot be found to update with id " + group.getId()); - throw new PersistenceException("The group cannot be found to update with id " + group.getId()); - } else if (getGroupQueryList.size() > 1) { - PolicyLogger.error(duplicateGroupId + group.getId() + deletedStatusFound); - throw new PersistenceException(duplicateGroupId + group.getId() + deletedStatusFound); - } - GroupEntity groupToUpdateInDB = (GroupEntity) getGroupQueryList.get(0); - if (!stringEquals(groupToUpdateInDB.getModifiedBy(), username)) { - groupToUpdateInDB.setModifiedBy(username); - } - if (group.getDescription() != null - && !stringEquals(group.getDescription(), groupToUpdateInDB.getDescription())) { - groupToUpdateInDB.setDescription(group.getDescription()); - } - // let's find out what policies have been deleted - StdPDPGroup oldGroup = null; - try { - oldGroup = (StdPDPGroup) papEngine.getGroup(group.getId()); - } catch (PAPException e1) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, policyDBDaoVar, - "We cannot get the group from the papEngine to delete policies"); - } - if (oldGroup == null) { - PolicyLogger.error("We cannot get the group from the papEngine to delete policies"); - } else { - Set<String> newPolicySet = new HashSet<>(group.getPolicies().size()); - // a multiple of n runtime is faster than n^2, so I am using a hashset to do the comparison - for (PDPPolicy pol : group.getPolicies()) { - newPolicySet.add(pol.getId()); - } - for (PDPPolicy pol : oldGroup.getPolicies()) { - // should be fast since getPolicies uses a HashSet in StdPDPGroup - if (!newPolicySet.contains(pol.getId())) { - String[] scopeAndName = getNameScopeAndVersionFromPdpPolicy(pol.getId()); - deletePolicyInScope(username, groupToUpdateInDB, pol, scopeAndName); - } - } - } - - if (group.getName() != null && !stringEquals(group.getName(), groupToUpdateInDB.getgroupName())) { - // we need to check if the new id exists in the database - String newGroupId = createNewPDPGroupId(group.getName()); - Query checkGroupQuery = em.createQuery(groupEntitySelectQuery); - checkGroupQuery.setParameter(groupIdVar, newGroupId); - checkGroupQuery.setParameter(deletedVar, false); - List<?> checkGroupQueryList; - try { - checkGroupQueryList = checkGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on checkGroupQuery.getResultList()"); - throw new PersistenceException(queryFailedToCheckExisting); - } - if (!checkGroupQueryList.isEmpty()) { - PolicyLogger.error("The new group name already exists, group id " + newGroupId); - throw new PersistenceException("The new group name already exists, group id " + newGroupId); - } - groupToUpdateInDB.setGroupId(newGroupId); - groupToUpdateInDB.setGroupName(group.getName()); - this.newGroupId = group.getId(); - } - em.flush(); - this.groupId = groupToUpdateInDB.getGroupKey(); - } - } - - private void deletePolicyInScope(String username, GroupEntity groupToUpdateInDB, PDPPolicy pol, - String[] scopeAndName) { - PolicyEntity policyToDelete; - if (scopeAndName == null) { - return; - } - try { - policyToDelete = getPolicy(scopeAndName[0], scopeAndName[1]); - if ("XACMLPapServlet.doDelete".equals(username)) { - Iterator<PolicyEntity> dbPolicyIt = groupToUpdateInDB.getPolicies().iterator(); - String policyName = getPolicyNameAndVersionFromPolicyFileName(policyToDelete.getPolicyName())[0]; - - logger.info("PolicyDBDao: delete policy from GroupEntity"); - deletePolicyFromGroupEntity(groupToUpdateInDB, policyToDelete, dbPolicyIt, policyName); - } - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Could not get policy to remove: " + pol.getId()); - throw new PersistenceException("Could not get policy to remove: " + pol.getId()); - } - } - - private void deletePolicyFromGroupEntity(GroupEntity groupToUpdateInDB, PolicyEntity policyToDelete, - Iterator<PolicyEntity> dbPolicyIt, String policyName) { - try { - while (dbPolicyIt.hasNext()) { - PolicyEntity dbpolicy = dbPolicyIt.next(); - if (policyToDelete.getScope().equals(dbpolicy.getScope()) - && getPolicyNameAndVersionFromPolicyFileName(dbpolicy.getPolicyName())[0] - .equals(policyName)) { - dbPolicyIt.remove(); - - logger.info("PolicyDBDao: deleting policy from the existing group:\n " + "policyName is " - + policyToDelete.getScope() + "." + policyToDelete.getPolicyName() + "\n" + "group is " - + groupToUpdateInDB.getGroupId()); - } - } - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error("Could not delete policy with name: " + policyToDelete.getScope() + "." - + policyToDelete.getPolicyName() + "\n ID: " + policyToDelete.getPolicyId()); - } - } - - @Override - public void addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int pdpJmxPort, - String username) { - logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, String pdpDescription, int " - + "pdpJmxPort, String username) as addPdpToGroup(" + pdpID + ", " + groupID + ", " + pdpName + ", " - + pdpDescription + ", " + pdpJmxPort + ", " + username + ") called"); - if (isNullOrEmpty(pdpID, groupID, pdpName, username)) { - throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty"); - } - synchronized (emLock) { - checkBeforeOperationRun(); - Query checkGroupQuery = em.createQuery(groupEntitySelectQuery); - checkGroupQuery.setParameter(groupIdVar, groupID); - checkGroupQuery.setParameter(deletedVar, false); - List<?> checkGroupQueryList; - try { - checkGroupQueryList = checkGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()"); - throw new PersistenceException(queryFailedToCheckExisting); - } - if (checkGroupQueryList.size() != 1) { - PolicyLogger.error("The group does not exist"); - throw new PersistenceException("The group does not exist"); - } - Query checkDuplicateQuery = em.createQuery(pdpEntitySelectQuery); - checkDuplicateQuery.setParameter(pdpIdVariable, pdpID); - checkDuplicateQuery.setParameter(deletedVar, false); - List<?> checkDuplicateList; - try { - checkDuplicateList = checkDuplicateQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check for duplicate PDP " + pdpID - + " on checkDuplicateQuery.getResultList()"); - throw new PersistenceException("Query failed trying to check for duplicate PDP " + pdpID); - } - PdpEntity newPdp; - if (!checkDuplicateList.isEmpty()) { - logger.warn("PDP already exists with id " + pdpID); - newPdp = (PdpEntity) checkDuplicateList.get(0); - } else { - newPdp = new PdpEntity(); - em.persist(newPdp); - } - - newPdp.setCreatedBy(username); - newPdp.setDeleted(false); - newPdp.setDescription(pdpDescription); - newPdp.setGroup((GroupEntity) checkGroupQueryList.get(0)); - newPdp.setJmxPort(pdpJmxPort); - newPdp.setModifiedBy(username); - newPdp.setPdpId(pdpID); - newPdp.setPdpName(pdpName); - - em.flush(); - this.pdpId = newPdp.getPdpKey(); - } - } - - - @Override - public void updatePdp(OnapPDP pdp, String username) { - logger.debug("updatePdp(PDP pdp, String username) as updatePdp(" + pdp + "," + username + ") called"); - if (pdp == null) { - throw new IllegalArgumentException("PDP pdp must not be null"); - } - if (isNullOrEmpty(pdp.getId(), username)) { - throw new IllegalArgumentException("pdp.getId() and username must not be null or empty"); - } - - synchronized (emLock) { - checkBeforeOperationRun(); - Query getPdpQuery = em.createQuery(pdpEntitySelectQuery); - getPdpQuery.setParameter(pdpIdVariable, pdp.getId()); - getPdpQuery.setParameter(deletedVar, false); - List<?> getPdpQueryList; - try { - getPdpQueryList = getPdpQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on getPdpQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get PDP " + pdp.getId()); - } - if (getPdpQueryList.isEmpty()) { - PolicyLogger.error("The pdp cannot be found to update with id " + pdp.getId()); - throw new PersistenceException("The pdp cannot be found to update with id " + pdp.getId()); - } else if (getPdpQueryList.size() > 1) { - PolicyLogger.error(moreThanOnePDP + pdp.getId() + deletedStatusFound); - throw new PersistenceException(moreThanOnePDP + pdp.getId() + deletedStatusFound); - } - PdpEntity pdpToUpdate = (PdpEntity) getPdpQueryList.get(0); - if (!stringEquals(pdpToUpdate.getModifiedBy(), username)) { - pdpToUpdate.setModifiedBy(username); - } - if (pdp.getDescription() != null && !stringEquals(pdp.getDescription(), pdpToUpdate.getDescription())) { - pdpToUpdate.setDescription(pdp.getDescription()); - } - if (pdp.getName() != null && !stringEquals(pdp.getName(), pdpToUpdate.getPdpName())) { - pdpToUpdate.setPdpName(pdp.getName()); - } - if (pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())) { - pdpToUpdate.setJmxPort(pdp.getJmxPort()); - } - - em.flush(); - this.pdpId = pdpToUpdate.getPdpKey(); - } - } - - @Override - public void movePdp(OnapPDP pdp, OnapPDPGroup group, String username) { - logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp(" + pdp + "," + group + "," - + username + ") called"); - if (pdp == null || group == null) { - throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null"); - } - if (isNullOrEmpty(username, pdp.getId(), group.getId())) { - throw new IllegalArgumentException( - "pdp.getId(), group.getId(), and username must not be null or empty"); - } - - synchronized (emLock) { - checkBeforeOperationRun(); - // check if pdp exists - Query getPdpQuery = em.createQuery(pdpEntitySelectQuery); - getPdpQuery.setParameter(pdpIdVariable, pdp.getId()); - getPdpQuery.setParameter(deletedVar, false); - List<?> getPdpQueryList; - try { - getPdpQueryList = getPdpQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on getPdpQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get pdp to move with id " + pdp.getId()); - } - if (getPdpQueryList.isEmpty()) { - PolicyLogger.error("The pdp cannot be found to move with id " + pdp.getId()); - throw new PersistenceException("The pdp cannot be found to move with id " + pdp.getId()); - } else if (getPdpQueryList.size() > 1) { - PolicyLogger.error(moreThanOnePDP + pdp.getId() + deletedStatusFound); - throw new PersistenceException(moreThanOnePDP + pdp.getId() + deletedStatusFound); - } - - // check if new group exists - Query checkGroupQuery = em.createQuery(groupEntitySelectQuery); - checkGroupQuery.setParameter(groupIdVar, group.getId()); - checkGroupQuery.setParameter(deletedVar, false); - List<?> checkGroupQueryList; - try { - checkGroupQueryList = checkGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get group on checkGroupQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get new group " + group.getId()); - } - if (checkGroupQueryList.size() != 1) { - PolicyLogger.error("The group " + group.getId() + " does not exist"); - throw new PersistenceException("The group " + group.getId() + " does not exist"); - } - GroupEntity groupToMoveInto = (GroupEntity) checkGroupQueryList.get(0); - PdpEntity pdpToUpdate = (PdpEntity) getPdpQueryList.get(0); - pdpToUpdate.setGroup(groupToMoveInto); - if (!stringEquals(pdpToUpdate.getModifiedBy(), username)) { - pdpToUpdate.setModifiedBy(username); - } - - em.flush(); - this.pdpId = pdpToUpdate.getPdpKey(); - } - } - - @Override - public void changeDefaultGroup(OnapPDPGroup group, String username) { - logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup(" + group + "," - + username + ") called"); - if (group == null) { - throw new IllegalArgumentException("PDPGroup group must not be null"); - } - if (isNullOrEmpty(group.getId(), username)) { - throw new IllegalArgumentException("group.getId() and username must not be null or empty"); - } - - synchronized (emLock) { - checkBeforeOperationRun(); - Query getGroupQuery = em.createQuery(groupEntitySelectQuery); - getGroupQuery.setParameter(groupIdVar, group.getId()); - getGroupQuery.setParameter(deletedVar, false); - List<?> getGroupQueryList; - try { - getGroupQueryList = getGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on getGroupQuery.getResultList()"); - throw new PersistenceException(queryFailedToGetGroup + group.getId()); - } - if (getGroupQueryList.isEmpty()) { - PolicyLogger.error("The group cannot be found to set default with id " + group.getId()); - throw new PersistenceException("The group cannot be found to set default with id " + group.getId()); - } else if (getGroupQueryList.size() > 1) { - PolicyLogger.error(duplicateGroupId + group.getId() + deletedStatusFound); - throw new PersistenceException(duplicateGroupId + group.getId() + deletedStatusFound); - } - GroupEntity newDefaultGroup = (GroupEntity) getGroupQueryList.get(0); - newDefaultGroup.setDefaultGroup(true); - if (!stringEquals(newDefaultGroup.getModifiedBy(), username)) { - newDefaultGroup.setModifiedBy(username); - } - - em.flush(); - this.groupId = newDefaultGroup.getGroupKey(); - Query setAllGroupsNotDefault = em.createQuery( - "UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup WHERE g.deleted=:deleted AND g" - + ".groupKey<>:groupKey"); - // not going to set modified by for all groups - setAllGroupsNotDefault.setParameter("defaultGroup", false); - setAllGroupsNotDefault.setParameter(deletedVar, false); - setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey()); - try { - logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default"); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception on setAllGroupsNotDefault.executeUpdate()"); - throw new PersistenceException("Could not set all other groups default to false"); - } - em.flush(); - } - } - - - @Override - public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) - throws PolicyDBException { - logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup(" + group - + ", " + moveToGroup + "," + username + ") called"); - if (group == null) { - throw new IllegalArgumentException("PDPGroup group cannot be null"); - } - if (isNullOrEmpty(username, group.getId())) { - throw new IllegalArgumentException("group.getId() and and username must not be null or empty"); - } - - if (group.isDefaultGroup()) { - PolicyLogger - .error("The default group " + group.getId() + " was attempted to be deleted. It cannot be."); - throw new PolicyDBException("You cannot delete the default group."); - } - synchronized (emLock) { - checkBeforeOperationRun(); - Query deleteGroupQuery = em.createQuery(groupEntitySelectQuery); - deleteGroupQuery.setParameter(groupIdVar, group.getId()); - deleteGroupQuery.setParameter(deletedVar, false); - List<?> deleteGroupQueryList; - try { - deleteGroupQueryList = deleteGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()"); - throw new PersistenceException("Query failed trying to check if group exists"); - } - if (deleteGroupQueryList.isEmpty()) { - logger.warn(groupCannotBeFound + group.getId()); - return; - } else if (deleteGroupQueryList.size() > 1) { - PolicyLogger.error(duplicateGroupId + group.getId() + foundInDBNotDeleted); - throw new PersistenceException(duplicateGroupId + group.getId() + foundInDBNotDeleted); - } - - Query pdpsInGroupQuery = - em.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted"); - pdpsInGroupQuery.setParameter("group", ((GroupEntity) deleteGroupQueryList.get(0))); - pdpsInGroupQuery.setParameter(deletedVar, false); - List<?> pdpsInGroupList; - try { - pdpsInGroupList = pdpsInGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()"); - throw new PersistenceException("Query failed trying to get PDPs in group"); - } - if (!pdpsInGroupList.isEmpty()) { - if (moveToGroup != null) { - Query checkMoveToGroupQuery = em.createQuery( - "SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted"); - checkMoveToGroupQuery.setParameter(groupIdVar, moveToGroup.getId()); - checkMoveToGroupQuery.setParameter(deletedVar, false); - List<?> checkMoveToGroupList; - try { - checkMoveToGroupList = checkMoveToGroupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check if group exists checkMoveToGroupQuery" - + ".getResultList()"); - throw new PersistenceException("Query failed trying to check if group exists"); - } - if (checkMoveToGroupList.isEmpty()) { - PolicyLogger.error(groupCannotBeFound + moveToGroup.getId()); - throw new PersistenceException(groupCannotBeFound + moveToGroup.getId()); - } else if (checkMoveToGroupList.size() > 1) { - PolicyLogger.error(duplicateGroupId + moveToGroup.getId() + foundInDBNotDeleted); - throw new PersistenceException( - duplicateGroupId + moveToGroup.getId() + foundInDBNotDeleted); - } else { - GroupEntity newGroup = (GroupEntity) checkMoveToGroupList.get(0); - for (Object pdpObject : pdpsInGroupList) { - PdpEntity pdp = (PdpEntity) pdpObject; - pdp.setGroup(newGroup); - if (!stringEquals(pdp.getModifiedBy(), username)) { - pdp.setModifiedBy(username); - } - try { - em.flush(); - this.newGroupId = newGroup.getGroupId(); - } catch (PersistenceException e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught PersistenceException trying to set pdp group to null on em.flush" - + "()"); - throw new PersistenceException("Query failed trying to set pdp group to "); - } - } - } - } else { - PolicyLogger.error("Group " + group.getId() - + " is trying to be delted with PDPs. No group was provided to move them to"); - throw new PolicyDBException("Group has PDPs. Must provide a group for them to move to"); - } - } - - // delete group here - GroupEntity groupToDelete = (GroupEntity) deleteGroupQueryList.get(0); - groupToDelete.setDeleted(true); - if (!stringEquals(groupToDelete.getModifiedBy(), username)) { - groupToDelete.setModifiedBy(username); - } - em.flush(); - this.groupId = groupToDelete.getGroupKey(); - } - } - - @Override - public StdPDPGroup addPolicyToGroup(String groupID, String policyID, String username) throws PolicyDBException { - logger.info("PolicyDBDao: addPolicyToGroup(String groupID, String policyID, String username) as " - + "addPolicyToGroup(" + groupID + ", " + policyID + "," + username + ") called"); - if (isNullOrEmpty(groupID, policyID, username)) { - throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty"); - } - synchronized (emLock) { - checkBeforeOperationRun(); - // check if group exists - Query groupQuery = em.createQuery(groupEntitySelectQuery); - groupQuery.setParameter(groupIdVar, groupID); - groupQuery.setParameter(deletedVar, false); - List<?> groupQueryList; - try { - groupQueryList = groupQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check if group exists groupQuery.getResultList()"); - throw new PersistenceException("Query failed trying to check if group " + groupID + " exists"); - } - if (groupQueryList.isEmpty()) { - PolicyLogger.error("Group policy is being added to does not exist with id " + groupID); - throw new PersistenceException("Group policy is being added to does not exist with id " + groupID); - } else if (groupQueryList.size() > 1) { - PolicyLogger.error(duplicateGroupId + groupID + foundInDBNotDeleted); - throw new PersistenceException(duplicateGroupId + groupID + foundInDBNotDeleted); - } - - // we need to convert the form of the policy id that is used groups into the form that is used - // for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml) - String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID); - if (policyNameScopeAndVersion == null) { - throw new IllegalArgumentException("Invalid input - policyID must contain name, scope and version"); - } - Query policyQuery = em.createQuery( - "SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName AND p.scope=:scope AND p" - + ".deleted=:deleted"); - policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]); - policyQuery.setParameter(scope, policyNameScopeAndVersion[1]); - policyQuery.setParameter(deletedVar, false); - List<?> policyQueryList; - try { - policyQueryList = policyQuery.getResultList(); - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check if policy exists policyQuery.getResultList()"); - throw new PersistenceException( - "Query failed trying to check if policy " + policyNameScopeAndVersion[0] + " exists"); - } - if (policyQueryList.isEmpty()) { - PolicyLogger.error("Policy being added to the group does not exist with policy id " - + policyNameScopeAndVersion[0]); - throw new PersistenceException("Policy being added to the group does not exist with policy id " - + policyNameScopeAndVersion[0]); - } else if (policyQueryList.size() > 1) { - PolicyLogger.error(duplicatePolicyId + policyNameScopeAndVersion[0] + foundInDBNotDeleted); - throw new PersistenceException( - duplicateGroupId + policyNameScopeAndVersion[0] + foundInDBNotDeleted); - } - logger.info("PolicyDBDao: Getting group and policy from database"); - GroupEntity group = (GroupEntity) groupQueryList.get(0); - PolicyEntity policy = (PolicyEntity) policyQueryList.get(0); - Iterator<PolicyEntity> policyIt = group.getPolicies().iterator(); - String policyName = getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0]; - - logger.info("PolicyDBDao: policyName retrieved is " + policyName); - try { - while (policyIt.hasNext()) { - PolicyEntity pol = policyIt.next(); - if (policy.getScope().equals(pol.getScope()) - && getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0] - .equals(policyName)) { - policyIt.remove(); - } - } - } catch (Exception e) { - logger.debug(e); - PolicyLogger.error("Could not delete old versions for policy " + policy.getPolicyName() + ", ID: " - + policy.getPolicyId()); - } - group.addPolicyToGroup(policy); - em.flush(); - - // After adding policy to the db group we need to make sure the filesytem group is in sync with the db - // group - try { - StdPDPGroup pdpGroup = (StdPDPGroup) papEngine.getGroup(group.getGroupId()); - return synchronizeGroupPoliciesInFileSystem(pdpGroup, group); - } catch (PAPException e) { - logger.debug(e); - PolicyLogger - .error("PolicyDBDao: Could not synchronize the filesystem group with the database group. " - + e.getMessage()); - } - return null; - } - } - - // this means delete pdp not just remove from group - @Override - public void removePdpFromGroup(String pdpID, String username) { - logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup(" + pdpID + "," - + username + ") called"); - if (isNullOrEmpty(pdpID, username)) { - throw new IllegalArgumentException("pdpID and username must not be null or empty"); - } - synchronized (emLock) { - checkBeforeOperationRun(); - Query pdpQuery = em.createQuery(pdpEntitySelectQuery); - pdpQuery.setParameter(pdpIdVariable, pdpID); - pdpQuery.setParameter(deletedVar, false); - List<?> pdpList; - try { - pdpList = pdpQuery.getResultList(); - } catch (Exception e) { - PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, policyDBDaoVar, - "Caught Exception trying to check if pdp exists pdpQuery.getResultList()"); - throw new PersistenceException("Query failed trying to check if pdp " + pdpID + " exists"); - } - if (pdpList.size() > 1) { - PolicyLogger.error("Somehow, more than one pdp with the id " + pdpID + foundInDBNotDeleted); - throw new PersistenceException( - "Somehow, more than one pdp with the id " + pdpID + foundInDBNotDeleted); - } else if (pdpList.isEmpty()) { - PolicyLogger.error("Pdp being removed does not exist with id " + pdpID); - return; - } - PdpEntity pdp = (PdpEntity) pdpList.get(0); - pdp.setGroup(null); - if (!stringEquals(pdp.getModifiedBy(), username)) { - pdp.setModifiedBy(username); - } - pdp.setDeleted(true); - - em.flush(); - this.pdpId = pdp.getPdpKey(); - } - } - - private void notifyOthers(long entityId, String entityType) { - notifyOthers(entityId, entityType, null); - } - - private void notifyOthers(long entityId, String entityType, String newGroupId) { - logger.debug("notifyOthers(long entityId, String entityType, long newGroupId) as notifyOthers(" + entityId - + "," + entityType + "," + newGroupId + ") called"); - LinkedList<Thread> notifyThreads = new LinkedList<>(); - - // we're going to run notifications in parallel threads to speed things up - for (Object obj : otherServers) { - Thread newNotifyThread = new Thread(new NotifyOtherThread(obj, entityId, entityType, newGroupId)); - newNotifyThread.start(); - notifyThreads.add(newNotifyThread); - } - // we want to wait for all notifications to complete or timeout before we unlock the interface and allow - // more changes - for (Thread t : notifyThreads) { - try { - t.join(); - } catch (Exception e) { - logger.warn("Could not join a notifcation thread" + e); - } - } - } - } - - private PolicyDBDao() { - // empty constructor - } - public static PolicyDBDaoTestClass getPolicyDBDaoTestClass() { return new PolicyDBDao().new PolicyDBDaoTestClass(); } @@ -2870,18 +809,14 @@ public class PolicyDBDao { String[] getPolicyNameAndVersionFromPolicyFileName(String originalPolicyName) throws PolicyDBException { return PolicyDBDao.this.getPolicyNameAndVersionFromPolicyFileName(originalPolicyName); } - + String[] getNameScopeAndVersionFromPdpPolicy(String fileName) { return PolicyDBDao.this.getNameScopeAndVersionFromPdpPolicy(fileName); } - + String getPdpPolicyName(String name, String scope) { return PolicyDBDao.this.getPdpPolicyName(name, scope); } - - Path getPolicySubFile(String inputFileName, String subFileType) { - return PolicyDBDao.this.getPolicySubFile(inputFileName, subFileType); - } } } diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java index d6ace7cf3..3cfe24524 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDBDaoTransaction.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-PAP-REST * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,10 +20,9 @@ package org.onap.policy.pap.xacml.rest.components; +import com.att.research.xacml.api.pap.PAPException; import java.util.List; - import javax.persistence.PersistenceException; - import org.onap.policy.rest.dao.PolicyDBException; import org.onap.policy.rest.jpa.GroupEntity; import org.onap.policy.rest.jpa.PdpEntity; @@ -31,13 +30,14 @@ import org.onap.policy.xacml.api.pap.OnapPDP; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.std.pap.StdPDPGroup; -import com.att.research.xacml.api.pap.PAPException; - public interface PolicyDBDaoTransaction { /** - * Commits (makes permanent) the current transaction. Also, notifies other PolicyDBDao instances on other PAP servers of the update. - * @throws IllegalStateException if the PolicyDBDao transaction has not been used or has been committed already. + * Commits (makes permanent) the current transaction. Also, notifies other PolicyDBDao instances + * on other PAP servers of the update. + * + * @throws IllegalStateException if the PolicyDBDao transaction has not been used or has been + * committed already. * @throws PersistenceException if the commit fails for some reason */ public void commitTransaction(); @@ -54,7 +54,9 @@ public interface PolicyDBDaoTransaction { /** * Check if the PolicyDBDaoTransaction is currently open - * @return False if the PolicyDBDao transaction has not been used or has been committed already, true if it is open. + * + * @return False if the PolicyDBDao transaction has not been used or has been committed already, + * true if it is open. */ public boolean isTransactionOpen(); @@ -64,7 +66,8 @@ public interface PolicyDBDaoTransaction { public void rollbackTransaction(); /** - * Close the PolicyDBDaoTransaction without rolling back or doing anything. Just used to close the EntityManager + * Close the PolicyDBDaoTransaction without rolling back or doing anything. Just used to close + * the Hibernate session. */ public void close(); @@ -79,7 +82,8 @@ public interface PolicyDBDaoTransaction { * @throws IllegalStateException If a transaction is already open * @throws PersistenceException If a database error occurs */ - public void createGroup(String groupID, String groupName, String groupDescription, String username) throws PolicyDBException; + public void createGroup(String groupID, String groupName, String groupDescription, String username) + throws PolicyDBException; /** * Updates a group in the database with a new name of description @@ -89,7 +93,7 @@ public interface PolicyDBDaoTransaction { * @throws IllegalStateException If a transaction is already open * @throws PersistenceException If a database error occurs or if the group can not be found */ - public void updateGroup(OnapPDPGroup group, String username) throws PolicyDBException; + public void updateGroup(OnapPDPGroup group, String requestType, String username) throws PolicyDBException; /** * Updates a PDP in the database with new information @@ -146,7 +150,8 @@ public interface PolicyDBDaoTransaction { * @throws PersistenceException If a database error occurs * @throws PolicyDBException */ - public StdPDPGroup addPolicyToGroup(String group, String policyID, String username) throws PolicyDBException; + public StdPDPGroup addPolicyToGroup(String group, String policyID, String requestType, String username) + throws PolicyDBException; /** @@ -158,7 +163,7 @@ public interface PolicyDBDaoTransaction { * @throws PersistenceException If a database error occurs * @throws PAPException If an error relating to how groups are handled occurs */ - public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username)throws PolicyDBException; + public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) throws PolicyDBException; /** * Removes an existing PDP from its group and deletes it. diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDbDaoTransactionInstance.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDbDaoTransactionInstance.java new file mode 100644 index 000000000..bc6c79583 --- /dev/null +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/PolicyDbDaoTransactionInstance.java @@ -0,0 +1,1538 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP-PAP-REST + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.xacml.rest.components; + +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.util.XACMLProperties; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.nio.file.InvalidPathException; +import java.nio.file.Paths; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.persistence.PersistenceException; +import javax.persistence.RollbackException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +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.rest.XACMLRestProperties; +import org.onap.policy.rest.adapter.PolicyRestAdapter; +import org.onap.policy.rest.dao.PolicyDBException; +import org.onap.policy.rest.jpa.ActionBodyEntity; +import org.onap.policy.rest.jpa.ConfigurationDataEntity; +import org.onap.policy.rest.jpa.GroupEntity; +import org.onap.policy.rest.jpa.PdpEntity; +import org.onap.policy.rest.jpa.PolicyEntity; +import org.onap.policy.xacml.api.pap.OnapPDP; +import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.onap.policy.xacml.std.pap.StdPDPGroup; +import org.onap.policy.xacml.util.XACMLPolicyWriter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType; +import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType; + + +@Component +public class PolicyDbDaoTransactionInstance implements PolicyDBDaoTransaction { + + private static final Logger logger = FlexLogger.getLogger(PolicyDbDaoTransactionInstance.class); + + private final Object emLock = new Object(); + long policyId; + long groupId; + long pdpId; + String newGroupId; + private boolean operationRun = false; + private Thread transactionTimer; + private static final String POLICY_NOTIFICATION = "policy"; + private static final String PDP_NOTIFICATION = "pdp"; + private static final String GROUP_NOTIFICATION = "group"; + + + private static final String DECISIONMS_MODEL = "MicroService_Model"; + public static boolean isJunit = false; + Session session; + + /** + * Instantiates a new policy DB dao transaction instance. + * + * @param test the test + */ + public PolicyDbDaoTransactionInstance(String test) { + // call the constructor with arguments + this(Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_TIMEOUT)), + Integer.parseInt(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_TRANS_WAIT))); + } + + public PolicyDbDaoTransactionInstance() { + // Default Constructor + } + + @Autowired + public PolicyDbDaoTransactionInstance(SessionFactory sessionfactory) { + PolicyDbDaoTransactionInstance.sessionfactory = sessionfactory; + } + + private static SessionFactory sessionfactory; + + + /** + * Instantiates a new policy DB dao transaction instance. + * + * @param transactionTimeout the transaction timeout is how long the transaction can sit before + * rolling back + * @param transactionWaitTime the transaction wait time is how long to wait for the transaction + * to start before + */ + public PolicyDbDaoTransactionInstance(int transactionTimeout, int transactionWaitTime) { + logger.info("\n\nPolicyDBDaoTransactionInstance() as PolicyDBDaoTransactionInstance() called:" + + "\n transactionTimeout = " + transactionTimeout + "\n transactionWaitTime = " + + transactionWaitTime + "\n\n"); + + policyId = -1; + groupId = -1; + pdpId = -1; + newGroupId = null; + synchronized (emLock) { + session = sessionfactory.openSession(); + try { + PolicyDBDao.getPolicyDBDaoInstance().startTransactionSynced(session, transactionWaitTime); + } catch (Exception e) { + logger.error("Could not lock transaction within " + transactionWaitTime + " milliseconds" + e); + throw new PersistenceException( + "Could not lock transaction within " + transactionWaitTime + " milliseconds"); + } + } + class TransactionTimer implements Runnable { + + private int sleepTime; + + public TransactionTimer(int timeout) { + this.sleepTime = timeout; + } + + @Override + public void run() { + if (logger.isDebugEnabled()) { + Date date = new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - SLEEPING: " + "\n sleepTime (ms) = " + sleepTime + + "\n TimeStamp = " + date.getTime() + "\n\n"); + } + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + // probably, the transaction was completed, the last thing + // we want to do is roll back + if (logger.isDebugEnabled()) { + Date date = new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - WAKE Interrupt: " + "\n TimeStamp = " + + date.getTime() + "\n\n"); + } + Thread.currentThread().interrupt(); + return; + } + if (logger.isDebugEnabled()) { + Date date = new java.util.Date(); + logger.debug("\n\nTransactionTimer.run() - WAKE Timeout: " + "\n TimeStamp = " + date.getTime() + + "\n\n"); + } + logger.warn("PolicyDBDaoTransactionInstance - TransactionTimer - Rolling back transaction."); + rollbackTransaction(); + } + + } + + transactionTimer = new Thread(new TransactionTimer(transactionTimeout), "transactionTimerThread"); + transactionTimer.start(); + + } + + private void checkBeforeOperationRun() { + checkBeforeOperationRun(false); + } + + private void checkBeforeOperationRun(boolean justCheckOpen) { + if (!isTransactionOpen()) { + PolicyLogger.warn("checkBeforeOperationRun - There is no transaction currently open"); + throw new IllegalStateException("There is no transaction currently open"); + } + if (operationRun && !justCheckOpen) { + PolicyLogger.warn("checkBeforeOperationRun - " + + "An operation has already been performed and the current transaction should be committed"); + throw new IllegalStateException( + "An operation has already been performed and the current transaction should be committed"); + } + operationRun = true; + } + + @Override + public void commitTransaction() { + synchronized (emLock) { + NotifyOtherPaps otherPaps = new NotifyOtherPaps(); + logger.debug("commitTransaction() as commitTransaction() called"); + if (!isTransactionOpen()) { + logger.warn( + "There is no open transaction to commit - PolicyId - " + policyId + ", GroupId - " + groupId); + try { + session.close(); + } catch (Exception e) { + logger.error("Exception Occured" + e); + } + return; + } + try { + session.getTransaction().commit(); + } catch (RollbackException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught RollbackException on em.getTransaction().commit()"); + throw new PersistenceException("The commit failed. Message:\n" + e.getMessage()); + } + session.close(); + // need to revisit + if (policyId >= 0) { + if (newGroupId != null) { + try { + otherPaps.notifyOthers(policyId, POLICY_NOTIFICATION, newGroupId); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on notifyOthers(" + policyId + "," + POLICY_NOTIFICATION + "," + + newGroupId + ")"); + } + } else { + try { + otherPaps.notifyOthers(policyId, POLICY_NOTIFICATION); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on notifyOthers(" + policyId + "," + POLICY_NOTIFICATION + ")"); + } + } + } + if (groupId >= 0) { + // we don't want commit to fail just because this does + if (newGroupId != null) { + try { + otherPaps.notifyOthers(groupId, GROUP_NOTIFICATION, newGroupId); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on notifyOthers(" + groupId + "," + GROUP_NOTIFICATION + "," + + newGroupId + ")"); + } + } else { + try { + otherPaps.notifyOthers(groupId, GROUP_NOTIFICATION); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on notifyOthers(" + groupId + "," + GROUP_NOTIFICATION + ")"); + } + } + } + if (pdpId >= 0) { + // we don't want commit to fail just because this does + try { + otherPaps.notifyOthers(pdpId, PDP_NOTIFICATION); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on notifyOthers(" + pdpId + "," + PDP_NOTIFICATION + ")"); + } + } + } + if (transactionTimer != null) { + transactionTimer.interrupt(); + } + } + + @Override + public void rollbackTransaction() { + logger.debug("rollbackTransaction() as rollbackTransaction() called"); + synchronized (emLock) { + if (isTransactionOpen()) { + try { + session.getTransaction().rollback(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Could not rollback transaction"); + } + try { + session.close(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Could not close Hibernate Session."); + } + + } else { + try { + session.close(); + } catch (Exception e) { + logger.warn("Could not close already closed transaction", e); + } + } + } + if (transactionTimer != null) { + transactionTimer.interrupt(); + } + } + + private void createPolicy(PolicyRestAdapter policy, String username, String policyScope, String inputPolicyName, + String policyDataString) { + String policyName = inputPolicyName; + logger.debug("createPolicy(PolicyRestAdapter policy, String username, String policyScope," + + " String policyName, String policyDataString) as createPolicy(" + policy + ", " + username + ", " + + policyScope + ", " + policyName + ", " + policyDataString + ") called"); + synchronized (emLock) { + PolicyDBDao policyDbDao = new PolicyDBDao(); + checkBeforeOperationRun(); + String configName = policyName; + if (policyName.contains("Config_")) { + policyName = policyName.replace(".Config_", ":Config_"); + } else if (policyName.contains("Action_")) { + policyName = policyName.replace(".Action_", ":Action_"); + } else if (policyName.contains("Decision_MS_")) { + policyName = policyName.replace(".Decision_MS_", ":Decision_MS_"); + } else if (policyName.contains("Decision_")) { + policyName = policyName.replace(".Decision_", ":Decision_"); + } + policyName = policyName.split(":")[1]; + Query createPolicyQuery = session + .createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"); + createPolicyQuery.setParameter(PolicyDBDao.SCOPE, policyScope); + createPolicyQuery.setParameter("policyName", policyName); + List<?> createPolicyQueryList = createPolicyQuery.list(); + PolicyEntity newPolicyEntity; + boolean update; + if (createPolicyQueryList.isEmpty()) { + newPolicyEntity = new PolicyEntity(); + update = false; + } else if (createPolicyQueryList.size() > 1) { + PolicyLogger.error("Somehow, more than one policy with the same " + + "scope, name, and deleted status were found in the database"); + throw new PersistenceException("Somehow, more than one policy with the same" + + " scope, name, and deleted status were found in the database"); + } else { + newPolicyEntity = (PolicyEntity) createPolicyQueryList.get(0); + update = true; + } + + ActionBodyEntity newActionBodyEntity = null; + if (policy.getPolicyType().equals(PolicyDBDao.ACTION)) { + boolean abupdate = false; + if (newPolicyEntity.getActionBodyEntity() == null) { + newActionBodyEntity = new ActionBodyEntity(); + } else { + newActionBodyEntity = (ActionBodyEntity) session.get(ActionBodyEntity.class, + newPolicyEntity.getActionBodyEntity().getActionBodyId()); + abupdate = true; + } + + if (newActionBodyEntity != null) { + // build the file path + // trim the .xml off the end + String policyNameClean = FilenameUtils.removeExtension(configName); + String actionBodyName = policyNameClean + ".json"; + + // get the action body + String actionBodyString = policy.getActionBody(); + if (actionBodyString == null) { + actionBodyString = "{}"; + } + newActionBodyEntity.setActionBody(actionBodyString); + newActionBodyEntity.setActionBodyName(actionBodyName); + newActionBodyEntity.setModifiedBy("PolicyDBDao.createPolicy()"); + newActionBodyEntity.setDeleted(false); + if (!abupdate) { + newActionBodyEntity.setCreatedBy("PolicyDBDao.createPolicy()"); + } + if (logger.isDebugEnabled()) { + logger.debug("\nPolicyDBDao.createPolicy" + "\n newActionBodyEntity.getActionBody() = " + + newActionBodyEntity.getActionBody() + + "\n newActionBodyEntity.getActionBodyName() = " + + newActionBodyEntity.getActionBodyName() + + "\n newActionBodyEntity.getModifiedBy() = " + newActionBodyEntity.getModifiedBy() + + "\n newActionBodyEntity.getCreatedBy() = " + newActionBodyEntity.getCreatedBy() + + "\n newActionBodyEntity.isDeleted() = " + newActionBodyEntity.isDeleted() + + "\n FLUSHING to DB"); + } + // push the actionBodyEntity to the DB + if (isJunit) { + newActionBodyEntity.prePersist(); + } + if (!abupdate) { + session.persist(newActionBodyEntity); + } + } else { + // newActionBodyEntity == null + // We have a actionBody in the policy but we found no + // actionBody in the DB + String msg = "\n\nPolicyDBDao.createPolicy - Incoming Action policy had an " + + "actionBody, but it could not be found in the DB for update." + "\n policyScope = " + + policyScope + "\n policyName = " + policyName + "\n\n"; + PolicyLogger.error("PolicyDBDao.createPolicy - Incoming Action policy had an actionBody, " + + "but it could not be found in the DB for update: policyName = " + policyName); + throw new IllegalArgumentException(msg); + } + } + + ConfigurationDataEntity newConfigurationDataEntity; + if (PolicyDBDao.CONFIG.equals(policy.getPolicyType()) + || DECISIONMS_MODEL.equals(policy.getRuleProvider())) { + boolean configUpdate; + if (newPolicyEntity.getConfigurationData() == null) { + newConfigurationDataEntity = new ConfigurationDataEntity(); + configUpdate = false; + } else { + newConfigurationDataEntity = (ConfigurationDataEntity) session.get(ConfigurationDataEntity.class, + newPolicyEntity.getConfigurationData().getConfigurationDataId()); + configUpdate = true; + } + + if (newConfigurationDataEntity != null) { + if (!PolicyDBDao.stringEquals(newConfigurationDataEntity.getConfigurationName(), + policyDbDao.getConfigFile(configName, policy))) { + newConfigurationDataEntity.setConfigurationName(policyDbDao.getConfigFile(configName, policy)); + } + if (newConfigurationDataEntity.getConfigType() == null + || !newConfigurationDataEntity.getConfigType().equals(policy.getConfigType())) { + newConfigurationDataEntity.setConfigType(policy.getConfigType()); + } + if (!configUpdate) { + newConfigurationDataEntity.setCreatedBy(username); + } + if (newConfigurationDataEntity.getModifiedBy() == null + || !newConfigurationDataEntity.getModifiedBy().equals(username)) { + newConfigurationDataEntity.setModifiedBy(username); + } + if (newConfigurationDataEntity.getDescription() == null + || !newConfigurationDataEntity.getDescription().equals("")) { + newConfigurationDataEntity.setDescription(""); + } + if (newConfigurationDataEntity.getConfigBody() == null + || newConfigurationDataEntity.getConfigBody().isEmpty() + || (!newConfigurationDataEntity.getConfigBody().equals(policy.getConfigBodyData()))) { + // hopefully one of these won't be null + if (policy.getConfigBodyData() == null || policy.getConfigBodyData().isEmpty()) { + newConfigurationDataEntity.setConfigBody(policy.getJsonBody()); + } else { + newConfigurationDataEntity.setConfigBody(policy.getConfigBodyData()); + } + } + if (newConfigurationDataEntity.isDeleted()) { + newConfigurationDataEntity.setDeleted(false); + } + if (isJunit) { + newConfigurationDataEntity.prePersist(); + } + if (!configUpdate) { + session.persist(newConfigurationDataEntity); + } + } else { + // We have a configurationData body in the policy but we + // found no configurationData body in the DB + String msg = "\n\nPolicyDBDao.createPolicy - Incoming Config policy had a " + + "configurationData body, but it could not be found in the DB for update." + + "\n policyScope = " + policyScope + "\n policyName = " + policyName + "\n\n"; + PolicyLogger + .error("PolicyDBDao.createPolicy - Incoming Config policy had a configurationData body, " + + "but it could not be found in the DB for update: policyName = " + policyName); + throw new IllegalArgumentException(msg); + } + + } else { + newConfigurationDataEntity = null; + } + policyId = newPolicyEntity.getPolicyId(); + + if (!PolicyDBDao.stringEquals(newPolicyEntity.getPolicyName(), policyName)) { + newPolicyEntity.setPolicyName(policyName); + } + if (!PolicyDBDao.stringEquals(newPolicyEntity.getCreatedBy(), username)) { + newPolicyEntity.setCreatedBy(username); + } + if (!PolicyDBDao.stringEquals(newPolicyEntity.getDescription(), policy.getPolicyDescription())) { + newPolicyEntity.setDescription(policy.getPolicyDescription()); + } + if (!PolicyDBDao.stringEquals(newPolicyEntity.getModifiedBy(), username)) { + newPolicyEntity.setModifiedBy(username); + } + if (!PolicyDBDao.stringEquals(newPolicyEntity.getPolicyData(), policyDataString)) { + newPolicyEntity.setPolicyData(policyDataString); + } + if (!PolicyDBDao.stringEquals(newPolicyEntity.getScope(), policyScope)) { + newPolicyEntity.setScope(policyScope); + } + if (newPolicyEntity.isDeleted()) { + newPolicyEntity.setDeleted(false); + } + newPolicyEntity.setConfigurationData(newConfigurationDataEntity); + newPolicyEntity.setActionBodyEntity(newActionBodyEntity); + if (isJunit) { + newPolicyEntity.prePersist(); + } + if (!update) { + session.persist(newPolicyEntity); + } + session.flush(); + this.policyId = newPolicyEntity.getPolicyId(); + } + return; + } + + @Override + public void createPolicy(Policy policy, String username) { + InputStream policyXmlStream = null; + try { + logger.debug("createPolicy(PolicyRestAdapter policy, String username) as createPolicy(" + policy + "," + + username + ") called"); + String policyScope = policy.policyAdapter.getDomainDir().replace(File.separator, "."); + // Does not need to be XACMLPolicyWriterWithPapNotify since it is + // already in the PAP + // and this transaction is intercepted up stream. + String policyDataString; + + try { + if (policy.policyAdapter.getData() instanceof PolicySetType) { + policyXmlStream = XACMLPolicyWriter + .getPolicySetXmlAsInputStream((PolicySetType) policy.getCorrectPolicyDataObject()); + } else { + policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream(policy.getCorrectPolicyDataObject()); + } + policyDataString = IOUtils.toString(policyXmlStream); + } catch (IOException e) { + policyDataString = "could not read"; + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught IOException on IOUtils.toString(" + policyXmlStream + ")"); + throw new IllegalArgumentException("Cannot parse the policy xml from the PolicyRestAdapter."); + } + + IOUtils.closeQuietly(policyXmlStream); + if (PolicyDBDao.isJunit) { + // Using parentPath object to set policy data. + policyDataString = policy.policyAdapter.getParentPath(); + } + String configPath = ""; + if (PolicyDBDao.CONFIG.equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { + configPath = evaluateXPath( + "/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'ID')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", + policyDataString); + } else if (PolicyDBDao.ACTION.equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { + configPath = evaluateXPath( + "/Policy/Rule/ObligationExpressions/ObligationExpression[contains(@ObligationId, " + + policy.policyAdapter.getActionAttribute() + + ")]/AttributeAssignmentExpression[@AttributeId='body']/AttributeValue/text()", + policyDataString); + } else if (DECISIONMS_MODEL.equalsIgnoreCase(policy.policyAdapter.getRuleProvider())) { + configPath = evaluateXPath( + "/Policy/Rule/AdviceExpressions/AdviceExpression[contains(@AdviceId,'MicroService')]/AttributeAssignmentExpression[@AttributeId='URLID']/AttributeValue/text()", + policyDataString); + } + + String prefix = null; + if (PolicyDBDao.CONFIG.equalsIgnoreCase(policy.policyAdapter.getPolicyType()) + || DECISIONMS_MODEL.equalsIgnoreCase(policy.policyAdapter.getRuleProvider())) { + prefix = configPath.substring(configPath.indexOf(policyScope + ".") + policyScope.concat(".").length(), + configPath.lastIndexOf(policy.policyAdapter.getPolicyName())); + if (PolicyDBDao.isNullOrEmpty(policy.policyAdapter.getConfigBodyData())) { + String configData = ""; + try { + String newConfigPath = configPath; + try { + newConfigPath = processConfigPath(newConfigPath); + } catch (Exception e2) { + logger.error("Could not process config path: " + newConfigPath, e2); + } + configData = readConfigFile(newConfigPath); + } catch (Exception e) { + logger.error("Could not read config body data for " + configPath, e); + } + policy.policyAdapter.setConfigBodyData(configData); + } + } else if (PolicyDBDao.ACTION.equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { + prefix = "Action_"; + } else if ("Decision".equalsIgnoreCase(policy.policyAdapter.getPolicyType())) { + prefix = "Decision_"; + } + + if (!(policy.policyAdapter.getData() instanceof PolicyType) + && !(policy.policyAdapter.getData() instanceof PolicySetType)) { + PolicyLogger.error("The data field is not an instance of PolicyType"); + throw new IllegalArgumentException("The data field is not an instance of PolicyType"); + } + String finalName = policyScope + "." + prefix + policy.policyAdapter.getPolicyName() + "." + + policy.policyAdapter.getHighestVersion() + ".xml"; + if (policy.policyAdapter.getConfigType() == null || "".equals(policy.policyAdapter.getConfigType())) { + // get the config file extension + String ext = ""; + if (configPath != null && !"".equalsIgnoreCase(configPath)) { + ext = configPath.substring(configPath.lastIndexOf('.'), configPath.length());; + } + + if (ext.contains("txt")) { + policy.policyAdapter.setConfigType(PolicyDBDao.OTHER_CONFIG); + } else if (ext.contains("json")) { + policy.policyAdapter.setConfigType(PolicyDBDao.JSON_CONFIG); + } else if (ext.contains("xml")) { + policy.policyAdapter.setConfigType(PolicyDBDao.XML_CONFIG); + } else if (ext.contains("properties")) { + policy.policyAdapter.setConfigType(PolicyDBDao.PROPERTIES_CONFIG); + } else { + if (policy.policyAdapter.getPolicyType().equalsIgnoreCase(PolicyDBDao.ACTION)) { + policy.policyAdapter.setConfigType(PolicyDBDao.JSON_CONFIG); + } + } + } + + createPolicy(policy.policyAdapter, username, policyScope, finalName, policyDataString); + } finally { + if (policyXmlStream != null) { + try { + policyXmlStream.close(); + } catch (IOException e) { + logger.error("Exception Occured while closing input stream" + e); + } + } + } + } + + + public PolicyEntity getPolicy(int policyId) { + return getPolicy(policyId, null, null); + } + + public PolicyEntity getPolicy(String policyName, String scope) { + return getPolicy(-1, policyName, scope); + } + + private PolicyEntity getPolicy(int policyIdVar, String policyName, String scope) { + logger.debug("getPolicy(int policyId, String policyName) as " + " getPolicy(" + policyIdVar + "," + policyName + + ") called"); + if (policyIdVar < 0 && PolicyDBDao.isNullOrEmpty(policyName, scope)) { + throw new IllegalArgumentException("policyID must be at least 0 or policyName must be not null or blank"); + } + + synchronized (emLock) { + checkBeforeOperationRun(true); + // check if group exists + String policyId; + Query policyQuery; + if (!PolicyDBDao.isNullOrEmpty(policyName, scope)) { + policyId = policyName; + policyQuery = + session.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:name AND p.scope=:scope"); + policyQuery.setParameter("name", policyId); + policyQuery.setParameter("scope", scope); + } else { + policyId = String.valueOf(policyIdVar); + policyQuery = session.getNamedQuery("PolicyEntity.FindById"); + policyQuery.setParameter("id", policyId); + } + List<?> policyQueryList; + try { + policyQueryList = policyQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get policy with policyQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get policy " + policyId); + } + + if (policyQueryList.isEmpty()) { + PolicyLogger.error("Policy does not exist with id " + policyId); + throw new PersistenceException("Group policy is being added to does not exist with id " + policyId); + } else if (policyQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUP_POLICYID + policyId + PolicyDBDao.FOUND_IN_DB); + throw new PersistenceException(PolicyDBDao.DUP_POLICYID + policyId + PolicyDBDao.FOUND_IN_DB); + } + return (PolicyEntity) policyQueryList.get(0); + } + } + + @Override + public GroupEntity getGroup(long groupKey) { + logger.debug("getGroup(int groupKey) as getGroup(" + groupKey + ") called"); + if (groupKey < 0) { + throw new IllegalArgumentException("groupKey must be at least 0"); + } + synchronized (emLock) { + checkBeforeOperationRun(true); + // check if group exists + Query groupQuery = session.createQuery("SELECT g FROM GroupEntity g WHERE g.groupKey=:groupKey"); + groupQuery.setParameter("groupKey", groupKey); + List<?> groupQueryList; + try { + groupQueryList = groupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get group with groupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_GET_GROUP + groupKey); + } + if (groupQueryList.isEmpty()) { + PolicyLogger.error("Group does not exist with groupKey " + groupKey); + throw new PersistenceException("Group does not exist with groupKey " + groupKey); + } else if (groupQueryList.size() > 1) { + PolicyLogger + .error("Somehow, more than one group with the groupKey " + groupKey + PolicyDBDao.FOUND_IN_DB); + throw new PersistenceException( + "Somehow, more than one group with the groupKey " + groupKey + PolicyDBDao.FOUND_IN_DB); + } + return (GroupEntity) groupQueryList.get(0); + } + } + + @Override + public GroupEntity getGroup(String groupId) { + logger.debug("getGroup(String groupId) as getGroup(" + groupId + ") called"); + if (PolicyDBDao.isNullOrEmpty(groupId)) { + throw new IllegalArgumentException("groupId must not be null or empty"); + } + synchronized (emLock) { + checkBeforeOperationRun(true); + // check if group exists + Query groupQuery = session.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId"); + groupQuery.setParameter(PolicyDBDao.GROUP_ID, groupId); + List<?> groupQueryList; + try { + groupQueryList = groupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get group with groupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_GET_GROUP + groupId); + } + if (groupQueryList.isEmpty()) { + PolicyLogger.error("Group does not exist with id " + groupId); + throw new PersistenceException("Group does not exist with id " + groupId); + } else if (groupQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUPLICATE_GROUPID + groupId + PolicyDBDao.FOUND_IN_DB); + throw new PersistenceException(PolicyDBDao.DUPLICATE_GROUPID + groupId + PolicyDBDao.FOUND_IN_DB); + } + return (GroupEntity) groupQueryList.get(0); + } + } + + @Override + public List<?> getPdpsInGroup(long groupKey) { + logger.debug("getPdpsInGroup(int groupKey) as getPdpsInGroup(" + groupKey + ") called"); + if (groupKey < 0) { + throw new IllegalArgumentException("groupId must not be < 0"); + } + synchronized (emLock) { + checkBeforeOperationRun(true); + Query pdpsQuery = session.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group"); + pdpsQuery.setParameter("group", getGroup(groupKey)); + return pdpsQuery.list(); + } + } + + @Override + public PdpEntity getPdp(long pdpKey) { + logger.debug("getPdp(int pdpKey) as getPdp(" + pdpKey + ") called"); + if (pdpKey < 0) { + throw new IllegalArgumentException("pdpKey must be at least 0"); + } + synchronized (emLock) { + checkBeforeOperationRun(true); + // check if group exists + Query pdpQuery = session.createQuery("SELECT p FROM PdpEntity p WHERE p.pdpKey=:pdpKey"); + pdpQuery.setParameter("pdpKey", pdpKey); + List<?> pdpQueryList; + try { + pdpQueryList = pdpQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get pdp with pdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get pdp " + pdpKey); + } + if (pdpQueryList.isEmpty()) { + PolicyLogger.error("Pdp does not exist with pdpKey " + pdpKey); + throw new PersistenceException("Pdp does not exist with pdpKey " + pdpKey); + } else if (pdpQueryList.size() > 1) { + PolicyLogger.error("Somehow, more than one pdp with the pdpKey " + pdpKey + PolicyDBDao.FOUND_IN_DB); + throw new PersistenceException( + "Somehow, more than one pdp with the pdpKey " + pdpKey + PolicyDBDao.FOUND_IN_DB); + } + return (PdpEntity) pdpQueryList.get(0); + } + } + + @Override + public boolean isTransactionOpen() { + logger.debug("isTransactionOpen() as isTransactionOpen() called"); + synchronized (emLock) { + return session.isOpen() && session.getTransaction().isActive(); + } + } + + private String processConfigPath(String inputConfigPath) { + String configPath = inputConfigPath; + String webappsPath = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS); + if (webappsPath == null) { + logger.error("Webapps property does not exist"); + throw new IllegalArgumentException("Webapps property does not exist"); + } + configPath = configPath.replace("$URL", webappsPath); + // make sure the correct slashes are in + try { + configPath = Paths.get(configPath).toString(); + } catch (InvalidPathException e) { + logger.error("Invalid config path: " + configPath, e); + throw new IllegalArgumentException("Invalid config path: " + configPath); + } + return configPath; + } + + private String readConfigFile(String configPath) { + String configDataString = null; + InputStream configContentStream = null; + try { + configContentStream = new FileInputStream(configPath); + configDataString = IOUtils.toString(configContentStream); + } catch (FileNotFoundException e) { + logger.error("Caught FileNotFoundException on new FileInputStream(" + configPath + ")", e); + throw new IllegalArgumentException("The config file path does not exist"); + } catch (IOException e2) { + logger.error("Caught IOException on newIOUtils.toString(" + configContentStream + ")", e2); + throw new IllegalArgumentException("The config file path cannot be read"); + } finally { + IOUtils.closeQuietly(configContentStream); + } + if (configDataString == null) { + throw new IllegalArgumentException("The config file path cannot be read"); + } + return configDataString; + } + + + @Override + public void close() { + synchronized (emLock) { + if (session.isOpen()) { + if (session.getTransaction().isActive()) { + session.getTransaction().rollback(); + } + session.close(); + } + if (transactionTimer != null) { + transactionTimer.interrupt(); + } + } + } + + @Override + public void createGroup(String groupId, String groupName, String inputGroupDescription, String username) { + String groupDescription = inputGroupDescription; + logger.debug("deletePolicy(String policyToDeletes) as createGroup(" + groupId + ", " + groupName + ", " + + groupDescription + ") called"); + if (PolicyDBDao.isNullOrEmpty(groupId, groupName, username)) { + throw new IllegalArgumentException("groupId, groupName, and username must not be null or empty"); + } + if (groupDescription == null) { + groupDescription = ""; + } + + synchronized (emLock) { + checkBeforeOperationRun(); + Query checkGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + checkGroupQuery.setParameter(PolicyDBDao.GROUP_ID, groupId); + checkGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkGroupQueryList; + try { + checkGroupQueryList = checkGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on checkGroupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_FOR_GROUP); + } + if (!checkGroupQueryList.isEmpty()) { + PolicyLogger.error("The group being added already exists with id " + groupId); + throw new PersistenceException("The group being added already exists with id " + groupId); + } + GroupEntity newGroup = new GroupEntity(); + newGroup.setCreatedBy(username); + newGroup.setModifiedBy(username); + newGroup.setGroupName(groupName); + newGroup.setGroupId(groupId); + newGroup.setDescription(groupDescription); + if (isJunit) { + newGroup.prePersist(); + } + session.persist(newGroup); + session.flush(); + this.groupId = newGroup.getGroupKey(); + } + } + + @Override + public void updateGroup(OnapPDPGroup group, String requestType, String username) { + logger.info("PolicyDBDao: updateGroup(PDPGroup group) as updateGroup(" + group + "," + requestType + "," + + username + ") called"); + if (group == null) { + throw new IllegalArgumentException("PDPGroup group must not be null"); + } + if (PolicyDBDao.isNullOrEmpty(group.getId(), requestType)) { + throw new IllegalArgumentException("group.getId() and username must not be null or empty"); + } + + synchronized (emLock) { + PolicyDBDao policyDbDaoVar = new PolicyDBDao(); + checkBeforeOperationRun(); + Query getGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + getGroupQuery.setParameter(PolicyDBDao.GROUP_ID, group.getId()); + getGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> getGroupQueryList; + try { + getGroupQueryList = getGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on getGroupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_GET_GROUP + group.getId() + " for editing"); + } + if (getGroupQueryList.isEmpty()) { + PolicyLogger.error("The group cannot be found to update with id " + group.getId()); + throw new PersistenceException("The group cannot be found to update with id " + group.getId()); + } else if (getGroupQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + } + GroupEntity groupToUpdateInDb = (GroupEntity) getGroupQueryList.get(0); + if (!PolicyDBDao.stringEquals(groupToUpdateInDb.getModifiedBy(), requestType)) { + groupToUpdateInDb.setModifiedBy(requestType); + } + if (group.getDescription() != null + && !PolicyDBDao.stringEquals(group.getDescription(), groupToUpdateInDb.getDescription())) { + groupToUpdateInDb.setDescription(group.getDescription()); + } + // let's find out what policies have been deleted + StdPDPGroup oldGroup = null; + try { + oldGroup = (StdPDPGroup) PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(group.getId()); + } catch (PAPException e1) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e1, PolicyDBDao.POLICYDBDAO_VAR, + "We cannot get the group from the papEngine to delete policies"); + } + if (oldGroup == null) { + PolicyLogger.error("We cannot get the group from the papEngine to delete policies"); + } else { + Set<String> newPolicySet = new HashSet<>(group.getPolicies().size()); + // a multiple of n runtime is faster than n^2, so I am using a + // hashset to do the comparison + for (PDPPolicy pol : group.getPolicies()) { + newPolicySet.add(pol.getId()); + } + for (PDPPolicy pol : oldGroup.getPolicies()) { + // should be fast since getPolicies uses a HashSet in + // StdPDPGroup + if (!newPolicySet.contains(pol.getId())) { + String[] scopeAndName = policyDbDaoVar.getNameScopeAndVersionFromPdpPolicy(pol.getId()); + PolicyEntity policyToDelete = null; + try { + if (scopeAndName != null) { + policyToDelete = getPolicy(scopeAndName[0], scopeAndName[1]); + if ("XACMLPapServlet.doDelete".equals(requestType)) { + Iterator<PolicyEntity> dbPolicyIt = groupToUpdateInDb.getPolicies().iterator(); + String policyName = policyDbDaoVar.getPolicyNameAndVersionFromPolicyFileName( + policyToDelete.getPolicyName())[0]; + + logger.info("PolicyDBDao: delete policy from GroupEntity"); + try { + while (dbPolicyIt.hasNext()) { + PolicyEntity dbpolicy = dbPolicyIt.next(); + if (policyToDelete.getScope().equals(dbpolicy.getScope()) + && policyDbDaoVar.getPolicyNameAndVersionFromPolicyFileName( + dbpolicy.getPolicyName())[0].equals(policyName)) { + dbPolicyIt.remove(); + logger.info("PolicyDBDao: deleting policy from the existing group:\n " + + "policyName is " + policyToDelete.getScope() + "." + + policyToDelete.getPolicyName() + "\n" + "group is " + + groupToUpdateInDb.getGroupId()); + } + } + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error("Could not delete policy with name: " + + policyToDelete.getScope() + "." + policyToDelete.getPolicyName() + + "\n ID: " + policyToDelete.getPolicyId()); + } + } + } + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Could not get policy to remove: " + pol.getId()); + throw new PersistenceException("Could not get policy to remove: " + pol.getId()); + } + } + } + } + + if (group.getName() != null + && !PolicyDBDao.stringEquals(group.getName(), groupToUpdateInDb.getgroupName())) { + // we need to check if the new id exists in the database + String newGrpId = PolicyDBDao.createNewPDPGroupId(group.getName()); + Query checkGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + checkGroupQuery.setParameter(PolicyDBDao.GROUP_ID, newGrpId); + checkGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkGroupQueryList; + try { + checkGroupQueryList = checkGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on checkGroupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_FOR_GROUP); + } + if (!checkGroupQueryList.isEmpty()) { + PolicyLogger.error("The new group name already exists, group id " + newGrpId); + throw new PersistenceException("The new group name already exists, group id " + newGrpId); + } + groupToUpdateInDb.setGroupId(newGrpId); + groupToUpdateInDb.setGroupName(group.getName()); + this.newGroupId = group.getId(); + } + session.flush(); + this.groupId = groupToUpdateInDb.getGroupKey(); + } + } + + @Override + public void addPdpToGroup(String pdpId, String groupIdVar, String pdpName, String pdpDescription, int pdpJmxPort, + String username) { + logger.debug("addPdpToGroup(String pdpID, String groupID, String pdpName, " + + "String pdpDescription, int pdpJmxPort, String username) as addPdpToGroup(" + pdpId + ", " + + groupIdVar + ", " + pdpName + ", " + pdpDescription + ", " + pdpJmxPort + ", " + username + + ") called"); + if (PolicyDBDao.isNullOrEmpty(pdpId, groupIdVar, pdpName, username)) { + throw new IllegalArgumentException("pdpID, groupID, pdpName, and username must not be null or empty"); + } + synchronized (emLock) { + checkBeforeOperationRun(); + Query checkGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + checkGroupQuery.setParameter(PolicyDBDao.GROUP_ID, groupIdVar); + checkGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkGroupQueryList; + try { + checkGroupQueryList = checkGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check for existing group on checkGroupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_FOR_GROUP); + } + if (checkGroupQueryList.size() != 1) { + PolicyLogger.error("The group does not exist"); + throw new PersistenceException("The group does not exist"); + } + Query checkDuplicateQuery = session.createQuery(PolicyDBDao.PDPENTITY_SELECT); + checkDuplicateQuery.setParameter(PolicyDBDao.PDP_ID, pdpId); + checkDuplicateQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkDuplicateList; + try { + checkDuplicateList = checkDuplicateQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check for duplicate PDP " + pdpId + + " on checkDuplicateQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check for duplicate PDP " + pdpId); + } + PdpEntity newPdp; + if (!checkDuplicateList.isEmpty()) { + logger.warn("PDP already exists with id " + pdpId); + newPdp = (PdpEntity) checkDuplicateList.get(0); + } else { + newPdp = new PdpEntity(); + } + + newPdp.setCreatedBy(username); + newPdp.setDeleted(false); + newPdp.setDescription(pdpDescription); + newPdp.setGroup((GroupEntity) checkGroupQueryList.get(0)); + newPdp.setJmxPort(pdpJmxPort); + newPdp.setModifiedBy(username); + newPdp.setPdpId(pdpId); + newPdp.setPdpName(pdpName); + if (isJunit) { + newPdp.prePersist(); + } + session.persist(newPdp); + session.flush(); + this.pdpId = newPdp.getPdpKey(); + } + } + + @Override + public void updatePdp(OnapPDP pdp, String username) { + logger.debug("updatePdp(PDP pdp, String username) as updatePdp(" + pdp + "," + username + ") called"); + if (pdp == null) { + throw new IllegalArgumentException("PDP pdp must not be null"); + } + if (PolicyDBDao.isNullOrEmpty(pdp.getId(), username)) { + throw new IllegalArgumentException("pdp.getId() and username must not be null or empty"); + } + + synchronized (emLock) { + checkBeforeOperationRun(); + Query getPdpQuery = session.createQuery(PolicyDBDao.PDPENTITY_SELECT); + getPdpQuery.setParameter(PolicyDBDao.PDP_ID, pdp.getId()); + getPdpQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> getPdpQueryList; + try { + getPdpQueryList = getPdpQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on getPdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get PDP " + pdp.getId()); + } + if (getPdpQueryList.isEmpty()) { + PolicyLogger.error("The pdp cannot be found to update with id " + pdp.getId()); + throw new PersistenceException("The pdp cannot be found to update with id " + pdp.getId()); + } else if (getPdpQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.MORE_THAN_ONE_PDP + pdp.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + throw new PersistenceException( + PolicyDBDao.MORE_THAN_ONE_PDP + pdp.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + } + PdpEntity pdpToUpdate = (PdpEntity) getPdpQueryList.get(0); + if (!PolicyDBDao.stringEquals(pdpToUpdate.getModifiedBy(), username)) { + pdpToUpdate.setModifiedBy(username); + } + if (pdp.getDescription() != null + && !PolicyDBDao.stringEquals(pdp.getDescription(), pdpToUpdate.getDescription())) { + pdpToUpdate.setDescription(pdp.getDescription()); + } + if (pdp.getName() != null && !PolicyDBDao.stringEquals(pdp.getName(), pdpToUpdate.getPdpName())) { + pdpToUpdate.setPdpName(pdp.getName()); + } + if (pdp.getJmxPort() != null && !pdp.getJmxPort().equals(pdpToUpdate.getJmxPort())) { + pdpToUpdate.setJmxPort(pdp.getJmxPort()); + } + + session.flush(); + this.pdpId = pdpToUpdate.getPdpKey(); + } + } + + @Override + public void movePdp(OnapPDP pdp, OnapPDPGroup group, String username) { + logger.debug("movePdp(PDP pdp, PDPGroup group, String username) as movePdp(" + pdp + "," + group + "," + + username + ") called"); + if (pdp == null || group == null) { + throw new IllegalArgumentException("PDP pdp and PDPGroup group must not be null"); + } + if (PolicyDBDao.isNullOrEmpty(username, pdp.getId(), group.getId())) { + throw new IllegalArgumentException("pdp.getId(), group.getId(), and username must not be null or empty"); + } + + synchronized (emLock) { + checkBeforeOperationRun(); + // check if pdp exists + Query getPdpQuery = session.createQuery(PolicyDBDao.PDPENTITY_SELECT); + getPdpQuery.setParameter(PolicyDBDao.PDP_ID, pdp.getId()); + getPdpQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> getPdpQueryList; + try { + getPdpQueryList = getPdpQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on getPdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get pdp to move with id " + pdp.getId()); + } + if (getPdpQueryList.isEmpty()) { + PolicyLogger.error("The pdp cannot be found to move with id " + pdp.getId()); + throw new PersistenceException("The pdp cannot be found to move with id " + pdp.getId()); + } else if (getPdpQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.MORE_THAN_ONE_PDP + pdp.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + throw new PersistenceException( + PolicyDBDao.MORE_THAN_ONE_PDP + pdp.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + } + + // check if new group exists + Query checkGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + checkGroupQuery.setParameter(PolicyDBDao.GROUP_ID, group.getId()); + checkGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkGroupQueryList; + try { + checkGroupQueryList = checkGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get group on checkGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get new group " + group.getId()); + } + if (checkGroupQueryList.size() != 1) { + PolicyLogger.error("The group " + group.getId() + " does not exist"); + throw new PersistenceException("The group " + group.getId() + " does not exist"); + } + GroupEntity groupToMoveInto = (GroupEntity) checkGroupQueryList.get(0); + PdpEntity pdpToUpdate = (PdpEntity) getPdpQueryList.get(0); + pdpToUpdate.setGroup(groupToMoveInto); + if (!PolicyDBDao.stringEquals(pdpToUpdate.getModifiedBy(), username)) { + pdpToUpdate.setModifiedBy(username); + } + + session.flush(); + this.pdpId = pdpToUpdate.getPdpKey(); + } + } + + @Override + public void changeDefaultGroup(OnapPDPGroup group, String username) { + logger.debug("changeDefaultGroup(PDPGroup group, String username) as changeDefaultGroup(" + group + "," + + username + ") called"); + if (group == null) { + throw new IllegalArgumentException("PDPGroup group must not be null"); + } + if (PolicyDBDao.isNullOrEmpty(group.getId(), username)) { + throw new IllegalArgumentException("group.getId() and username must not be null or empty"); + } + + synchronized (emLock) { + checkBeforeOperationRun(); + Query getGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + getGroupQuery.setParameter(PolicyDBDao.GROUP_ID, group.getId()); + getGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> getGroupQueryList; + try { + getGroupQueryList = getGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on getGroupQuery.getResultList()"); + throw new PersistenceException(PolicyDBDao.QUERY_FAILED_GET_GROUP + group.getId()); + } + if (getGroupQueryList.isEmpty()) { + PolicyLogger.error("The group cannot be found to set default with id " + group.getId()); + throw new PersistenceException("The group cannot be found to set default with id " + group.getId()); + } else if (getGroupQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.DELETED_STATUS_FOUND); + } + GroupEntity newDefaultGroup = (GroupEntity) getGroupQueryList.get(0); + newDefaultGroup.setDefaultGroup(true); + if (!PolicyDBDao.stringEquals(newDefaultGroup.getModifiedBy(), username)) { + newDefaultGroup.setModifiedBy(username); + } + + session.flush(); + this.groupId = newDefaultGroup.getGroupKey(); + Query setAllGroupsNotDefault = session.createQuery("UPDATE GroupEntity g SET g.defaultGroup=:defaultGroup " + + "WHERE g.deleted=:deleted AND g.groupKey<>:groupKey"); + // not going to set modified by for all groups + setAllGroupsNotDefault.setParameter("defaultGroup", false); + setAllGroupsNotDefault.setParameter(PolicyDBDao.DELETED, false); + setAllGroupsNotDefault.setParameter("groupKey", newDefaultGroup.getGroupKey()); + try { + logger.info("set " + setAllGroupsNotDefault.executeUpdate() + " groups as not default"); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception on setAllGroupsNotDefault.executeUpdate()"); + throw new PersistenceException("Could not set all other groups default to false"); + } + session.flush(); + } + } + + @Override + public void deleteGroup(OnapPDPGroup group, OnapPDPGroup moveToGroup, String username) throws PolicyDBException { + logger.debug("deleteGroup(PDPGroup group, PDPGroup moveToGroup, String username) as deleteGroup(" + group + ", " + + moveToGroup + "," + username + ") called"); + if (group == null) { + throw new IllegalArgumentException("PDPGroup group cannot be null"); + } + if (PolicyDBDao.isNullOrEmpty(username, group.getId())) { + throw new IllegalArgumentException("group.getId() and and username must not be null or empty"); + } + + if (group.isDefaultGroup()) { + PolicyLogger.error("The default group " + group.getId() + " was attempted to be deleted. It cannot be."); + throw new PolicyDBException("You cannot delete the default group."); + } + synchronized (emLock) { + checkBeforeOperationRun(); + Query deleteGroupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + deleteGroupQuery.setParameter(PolicyDBDao.GROUP_ID, group.getId()); + deleteGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> deleteGroupQueryList; + try { + deleteGroupQueryList = deleteGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check if group exists deleteGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group exists"); + } + if (deleteGroupQueryList.isEmpty()) { + logger.warn(PolicyDBDao.GROUP_NOT_FOUND + group.getId()); + return; + } else if (deleteGroupQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + group.getId() + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + } + + Query pdpsInGroupQuery = + session.createQuery("SELECT p FROM PdpEntity p WHERE p.groupEntity=:group and p.deleted=:deleted"); + pdpsInGroupQuery.setParameter("group", (deleteGroupQueryList.get(0))); + pdpsInGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> pdpsInGroupList; + try { + pdpsInGroupList = pdpsInGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to get PDPs in group on pdpsInGroupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to get PDPs in group"); + } + if (!pdpsInGroupList.isEmpty()) { + if (moveToGroup != null) { + Query checkMoveToGroupQuery = session + .createQuery("SELECT o FROM GroupEntity o WHERE o.groupId=:groupId AND o.deleted=:deleted"); + checkMoveToGroupQuery.setParameter(PolicyDBDao.GROUP_ID, moveToGroup.getId()); + checkMoveToGroupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> checkMoveToGroupList; + try { + checkMoveToGroupList = checkMoveToGroupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check if group exists checkMoveToGroupQuery.getResultList"); + throw new PersistenceException("Query failed trying to check if group exists"); + } + if (checkMoveToGroupList.isEmpty()) { + PolicyLogger.error(PolicyDBDao.GROUP_NOT_FOUND + moveToGroup.getId()); + throw new PersistenceException(PolicyDBDao.GROUP_NOT_FOUND + moveToGroup.getId()); + } else if (checkMoveToGroupList.size() > 1) { + PolicyLogger.error( + PolicyDBDao.DUPLICATE_GROUPID + moveToGroup.getId() + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + moveToGroup.getId() + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + } else { + GroupEntity newGroup = (GroupEntity) checkMoveToGroupList.get(0); + for (Object pdpObject : pdpsInGroupList) { + PdpEntity pdp = (PdpEntity) pdpObject; + pdp.setGroup(newGroup); + if (!PolicyDBDao.stringEquals(pdp.getModifiedBy(), username)) { + pdp.setModifiedBy(username); + } + try { + session.flush(); + this.newGroupId = newGroup.getGroupId(); + } catch (PersistenceException e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught PersistenceException trying to set pdp group to null on em.flush()"); + throw new PersistenceException("Query failed trying to set pdp group to "); + } + } + } + } else { + PolicyLogger.error("Group " + group.getId() + + " is trying to be delted with PDPs. No group was provided to move them to"); + throw new PolicyDBException("Group has PDPs. Must provide a group for them to move to"); + } + } + + // delete group here + GroupEntity groupToDelete = (GroupEntity) deleteGroupQueryList.get(0); + groupToDelete.setDeleted(true); + if (!PolicyDBDao.stringEquals(groupToDelete.getModifiedBy(), username)) { + groupToDelete.setModifiedBy(username); + } + session.flush(); + this.groupId = groupToDelete.getGroupKey(); + } + } + + @Override + public StdPDPGroup addPolicyToGroup(String groupIdVar, String policyIdVar, String requestType, String username) + throws PolicyDBException { + logger.info( + "PolicyDBDao: addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup(" + + groupIdVar + ", " + policyIdVar + "," + requestType + "," + username + ") called"); + if (PolicyDBDao.isNullOrEmpty(groupIdVar, policyIdVar, requestType)) { + throw new IllegalArgumentException("groupID, policyID, and username must not be null or empty"); + } + synchronized (emLock) { + checkBeforeOperationRun(); + // check if group exists + Query groupQuery = session.createQuery(PolicyDBDao.GROUPENTITY_SELECT); + groupQuery.setParameter(PolicyDBDao.GROUP_ID, groupIdVar); + groupQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> groupQueryList; + try { + groupQueryList = groupQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check if group exists groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group " + groupIdVar + " exists"); + } + if (groupQueryList.isEmpty()) { + PolicyLogger.error("Group policy is being added to does not exist with id " + groupIdVar); + throw new PersistenceException("Group policy is being added to does not exist with id " + groupIdVar); + } else if (groupQueryList.size() > 1) { + PolicyLogger.error(PolicyDBDao.DUPLICATE_GROUPID + groupIdVar + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + groupIdVar + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + } + + // we need to convert the form of the policy id that is used groups + // into the form that is used + // for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml) + PolicyDBDao policyDbDao = new PolicyDBDao(); + String[] policyNameScopeAndVersion = policyDbDao.getNameScopeAndVersionFromPdpPolicy(policyIdVar); + if (policyNameScopeAndVersion == null) { + throw new IllegalArgumentException("Invalid input - policyID must contain name, scope and version"); + } + Query policyQuery = session.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:policyName " + + "AND p.scope=:scope AND p.deleted=:deleted"); + policyQuery.setParameter("policyName", policyNameScopeAndVersion[0]); + policyQuery.setParameter(PolicyDBDao.SCOPE, policyNameScopeAndVersion[1]); + policyQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> policyQueryList; + try { + policyQueryList = policyQuery.list(); + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check if policy exists policyQuery.getResultList()"); + throw new PersistenceException( + "Query failed trying to check if policy " + policyNameScopeAndVersion[0] + " exists"); + } + if (policyQueryList.isEmpty()) { + PolicyLogger.error("Policy being added to the group does not exist with policy id " + + policyNameScopeAndVersion[0]); + throw new PersistenceException("Policy being added to the group does not exist with policy id " + + policyNameScopeAndVersion[0]); + } else if (policyQueryList.size() > 1) { + PolicyLogger.error( + PolicyDBDao.DUP_POLICYID + policyNameScopeAndVersion[0] + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + throw new PersistenceException( + PolicyDBDao.DUPLICATE_GROUPID + policyNameScopeAndVersion[0] + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + } + logger.info("PolicyDBDao: Getting group and policy from database"); + GroupEntity group = (GroupEntity) groupQueryList.get(0); + PolicyEntity policy = (PolicyEntity) policyQueryList.get(0); + Iterator<PolicyEntity> policyIt = group.getPolicies().iterator(); + String policyName = policyDbDao.getPolicyNameAndVersionFromPolicyFileName(policy.getPolicyName())[0]; + + logger.info("PolicyDBDao: policyName retrieved is " + policyName); + try { + while (policyIt.hasNext()) { + PolicyEntity pol = policyIt.next(); + if (policy.getScope().equals(pol.getScope()) + && policyDbDao.getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0] + .equals(policyName)) { + policyIt.remove(); + } + } + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error("Could not delete old versions for policy " + policy.getPolicyName() + ", ID: " + + policy.getPolicyId()); + } + group.addPolicyToGroup(policy); + session.flush(); + + // After adding policy to the db group we need to make sure the + // filesytem group is in sync with the db group + try { + StdPDPGroup pdpGroup = + (StdPDPGroup) PolicyDBDao.getPolicyDBDaoInstance().getPapEngine().getGroup(group.getGroupId()); + return policyDbDao.synchronizeGroupPoliciesInFileSystem(pdpGroup, group); + } catch (PAPException e) { + logger.debug(e); + PolicyLogger.error("PolicyDBDao: Could not synchronize the filesystem group with the database group. " + + e.getMessage()); + } + return null; + } + } + + // this means delete pdp not just remove from group + @Override + public void removePdpFromGroup(String pdpId, String username) { + logger.debug("removePdpFromGroup(String pdpID, String username) as removePdpFromGroup(" + pdpId + "," + username + + ") called"); + if (PolicyDBDao.isNullOrEmpty(pdpId, username)) { + throw new IllegalArgumentException("pdpID and username must not be null or empty"); + } + synchronized (emLock) { + checkBeforeOperationRun(); + Query pdpQuery = session.createQuery(PolicyDBDao.PDPENTITY_SELECT); + pdpQuery.setParameter(PolicyDBDao.PDP_ID, pdpId); + pdpQuery.setParameter(PolicyDBDao.DELETED, false); + List<?> pdpList; + try { + pdpList = pdpQuery.list(); + } catch (Exception e) { + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, PolicyDBDao.POLICYDBDAO_VAR, + "Caught Exception trying to check if pdp exists pdpQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if pdp " + pdpId + " exists"); + } + if (pdpList.size() > 1) { + PolicyLogger.error("Somehow, more than one pdp with the id " + pdpId + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + throw new PersistenceException( + "Somehow, more than one pdp with the id " + pdpId + PolicyDBDao.FOUND_IN_DB_NOT_DEL); + } else if (pdpList.isEmpty()) { + PolicyLogger.error("Pdp being removed does not exist with id " + pdpId); + return; + } + PdpEntity pdp = (PdpEntity) pdpList.get(0); + if (!isJunit) { + pdp.setGroup(null); + } + + if (!PolicyDBDao.stringEquals(pdp.getModifiedBy(), username)) { + pdp.setModifiedBy(username); + } + pdp.setDeleted(true); + + session.flush(); + this.pdpId = pdp.getPdpKey(); + } + } + + private static String evaluateXPath(String expression, String xml) { + InputSource source = new InputSource(new StringReader(xml)); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + String description = ""; + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(source); + + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + + description = xpath.evaluate(expression, document); + } catch (Exception e) { + logger.error("Exception Occured while evaluating path" + e); + } + return description; + } +} diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/PushPolicyController.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/PushPolicyController.java index eec34b642..17fce7142 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/PushPolicyController.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/PushPolicyController.java @@ -2,7 +2,7 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,13 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.pap.xacml.rest.controller; +import com.att.research.xacml.api.pap.PAPException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -27,12 +32,9 @@ import java.io.ObjectOutputStream; import java.net.URI; import java.util.List; import java.util.UUID; - -import javax.persistence.EntityManager; -import javax.persistence.Query; +import javax.script.SimpleBindings; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; import org.onap.policy.common.logging.flexlogger.FlexLogger; @@ -48,11 +50,6 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import com.att.research.xacml.api.pap.PAPException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - @Controller public class PushPolicyController { private static final Logger LOGGER = FlexLogger.getLogger(PushPolicyController.class); @@ -144,13 +141,15 @@ public class PushPolicyController { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } - //Get PolicyEntity from DB; - EntityManager em = XACMLPapServlet.getEmf().createEntityManager(); - Query createPolicyQuery = - em.createQuery("SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"); - createPolicyQuery.setParameter("scope", policyScope); - createPolicyQuery.setParameter(policyNames, policyName.substring(policyScope.length() + 1)); - List<?> createPolicyQueryList = createPolicyQuery.getResultList(); + // Get PolicyEntity from DB; + String createPolicyQuery = "SELECT p FROM PolicyEntity p WHERE p.scope=:scope AND p.policyName=:policyName"; + SimpleBindings params = new SimpleBindings(); + params.put("scope", policyScope); + params.put(policyNames, policyName.substring(policyScope.length() + 1)); + List<?> createPolicyQueryList = commonClassDao.getDataByQuery(createPolicyQuery, params); + LOGGER.info("addPolicyToGroup:Total execution time to retrieve " + policyNames + + " from PolicyEntity"); + PolicyEntity policyEntity = null; if (!createPolicyQueryList.isEmpty()) { policyEntity = (PolicyEntity) createPolicyQueryList.get(0); diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DeleteHandler.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DeleteHandler.java index f71af87cc..ca0bb775a 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DeleteHandler.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DeleteHandler.java @@ -2,7 +2,7 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,20 +19,16 @@ */ package org.onap.policy.pap.xacml.rest.handler; +import com.att.research.xacml.api.pap.PAPException; +import com.att.research.xacml.api.pap.PDPPolicy; +import com.att.research.xacml.util.XACMLProperties; import java.io.File; import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.Query; +import javax.script.SimpleBindings; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.onap.policy.common.logging.ONAPLoggingContext; import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; @@ -43,8 +39,8 @@ import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction; import org.onap.policy.pap.xacml.rest.elk.client.PolicyElasticSearchController; import org.onap.policy.pap.xacml.rest.model.RemoveGroupPolicy; import org.onap.policy.pap.xacml.rest.util.JPAUtils; -import org.onap.policy.rest.XACMLRestProperties; import org.onap.policy.rest.adapter.PolicyRestAdapter; +import org.onap.policy.rest.dao.CommonClassDao; import org.onap.policy.rest.jpa.PolicyEntity; import org.onap.policy.rest.jpa.PolicyVersion; import org.onap.policy.utils.PolicyUtils; @@ -52,13 +48,23 @@ import org.onap.policy.xacml.api.XACMLErrorConstants; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.std.pap.StdPAPPolicy; import org.onap.policy.xacml.std.pap.StdPDPGroup; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -import com.att.research.xacml.api.pap.PAPException; -import com.att.research.xacml.api.pap.PDPPolicy; -import com.att.research.xacml.util.XACMLProperties; - +@Component public class DeleteHandler { + private static CommonClassDao commonClassDao; + + @Autowired + public DeleteHandler(CommonClassDao commonClassDao) { + DeleteHandler.commonClassDao = commonClassDao; + } + + public DeleteHandler() { + // Default Constructor + } + private OnapPDPGroup newgroup; private static Logger logger = FlexLogger.getLogger(DeleteHandler.class); public static final String POLICY_IN_PDP = "PolicyInPDP"; @@ -88,14 +94,8 @@ public class DeleteHandler { PolicyEntity policyEntity = null; JPAUtils jpaUtils = null; - String papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER); - String papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL); - String papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER); - String papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD); - Connection con = null; - try { - jpaUtils = JPAUtils.getJPAUtilsInstance(XACMLPapServlet.getEmf()); + jpaUtils = JPAUtils.getJPAUtilsInstance(); } catch (Exception e) { PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP"); @@ -111,8 +111,7 @@ public class DeleteHandler { response.setStatus(HttpServletResponse.SC_ACCEPTED); return; } - EntityManager em = XACMLPapServlet.getEmf().createEntityManager(); - Query policyEntityQuery = null; + String policyEntityQuery = null; try { if (policyName.endsWith(".xml")) { removeXMLExtension = policyName.replace(".xml", ""); @@ -137,8 +136,8 @@ public class DeleteHandler { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } - policyEntityQuery = em.createQuery( - "SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope"); + policyEntityQuery = + "SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope"; } else if (policy.getDeleteCondition().equalsIgnoreCase("Current Version")) { if (policyName.contains("Config_")) { splitPolicyName = policyName.replace(".Config_", ":Config_"); @@ -149,34 +148,30 @@ public class DeleteHandler { } split = splitPolicyName.split(":"); queryCheck = false; - policyEntityQuery = em.createQuery( - "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope"); + policyEntityQuery = "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope"; } - + SimpleBindings params = new SimpleBindings(); if (queryCheck) { - policyEntityQuery.setParameter("pName", "%" + split[1] + "%"); + params.put("pName", "%" + split[1] + "%"); } else { - policyEntityQuery.setParameter("pName", split[1]); + params.put("pName", split[1]); } - policyEntityQuery.setParameter("pScope", split[0]); - List<?> peResult = policyEntityQuery.getResultList(); + params.put("pScope", split[0]); + List<?> peResult = commonClassDao.getDataByQuery(policyEntityQuery, params); if (!peResult.isEmpty()) { - Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname"); - getPolicyVersion.setParameter("pname", removeVersionExtension.replace(".", File.separator)); - List<?> pvResult = getPolicyVersion.getResultList(); + String getPolicyVersion = "Select p from PolicyVersion p where p.policyName=:pname"; + SimpleBindings pvParams = new SimpleBindings(); + pvParams.put("pname", removeVersionExtension.replace(".", File.separator)); + List<?> pvResult = commonClassDao.getDataByQuery(getPolicyVersion, pvParams); PolicyVersion pVersion = (PolicyVersion) pvResult.get(0); int newVersion = 0; - em.getTransaction().begin(); - Class.forName(papDbDriver); - con = DriverManager.getConnection(papDbUrl, papDbUser, papDbPassword); - if (policy.getDeleteCondition().equalsIgnoreCase("All Versions")) { - boolean groupCheck = checkPolicyGroupEntity(con, peResult); + boolean groupCheck = checkPolicyGroupEntity(peResult); if (!groupCheck) { for (Object peData : peResult) { policyEntity = (PolicyEntity) peData; - status = deletePolicyEntityData(em, policyEntity); + status = deletePolicyEntityData(policyEntity); } } else { status = POLICY_IN_PDP; @@ -197,7 +192,7 @@ public class DeleteHandler { default: try { policyVersionDeleted = true; - em.remove(pVersion); + commonClassDao.delete(pVersion); } catch (Exception e) { logger.error(e.getMessage(), e); policyVersionDeleted = false; @@ -205,10 +200,10 @@ public class DeleteHandler { break; } } else if (policy.getDeleteCondition().equalsIgnoreCase("Current Version")) { - boolean groupCheck = checkPolicyGroupEntity(con, peResult); + boolean groupCheck = checkPolicyGroupEntity(peResult); if (!groupCheck) { policyEntity = (PolicyEntity) peResult.get(0); - status = deletePolicyEntityData(em, policyEntity); + status = deletePolicyEntityData(policyEntity); } else { status = POLICY_IN_PDP; } @@ -242,7 +237,7 @@ public class DeleteHandler { pVersion.setHigherVersion(newVersion); try { policyVersionDeleted = true; - em.persist(pVersion); + commonClassDao.save(pVersion); } catch (Exception e) { logger.error(e.getMessage(), e); policyVersionDeleted = false; @@ -250,7 +245,7 @@ public class DeleteHandler { } else { try { policyVersionDeleted = true; - em.remove(pVersion); + commonClassDao.delete(pVersion); } catch (Exception e) { logger.error(e.getMessage(), e); policyVersionDeleted = false; @@ -267,18 +262,11 @@ public class DeleteHandler { return; } } - em.getTransaction().commit(); } catch (Exception e) { - em.getTransaction().rollback(); PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR"); response.addHeader(ERROR, "deleteDB"); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; - } finally { - em.close(); - if (con != null) { - con.close(); - } } if (policyVersionDeleted) { @@ -294,20 +282,20 @@ public class DeleteHandler { } } - public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity) { + public static String deletePolicyEntityData(PolicyEntity policyEntity) { PolicyElasticSearchController controller = new PolicyElasticSearchController(); PolicyRestAdapter policyData = new PolicyRestAdapter(); String policyName = policyEntity.getPolicyName(); try { - if (policyName.contains("Config_")) { - em.remove(policyEntity.getConfigurationData()); + if (policyName.contains("Config_") || policyName.contains("Decision_MS_")) { + commonClassDao.delete(policyEntity.getConfigurationData()); } else if (policyName.contains("Action_")) { - em.remove(policyEntity.getActionBodyEntity()); + commonClassDao.delete(policyEntity.getActionBodyEntity()); } String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName(); policyData.setNewFileName(searchPolicyName); controller.deleteElk(policyData); - em.remove(policyEntity); + commonClassDao.delete(policyEntity); } catch (Exception e) { logger.error(e.getMessage(), e); return ERROR; @@ -315,16 +303,15 @@ public class DeleteHandler { return "success"; } - public static boolean checkPolicyGroupEntity(Connection con, List<?> peResult) throws SQLException { + public static boolean checkPolicyGroupEntity(List<?> peResult) { + String groupEntityquery = "from PolicyGroupEntity where policyid = :policyEntityId"; for (Object peData : peResult) { PolicyEntity policyEntity = (PolicyEntity) peData; - try (Statement st = con.createStatement(); - ResultSet rs = st.executeQuery( - "Select * from PolicyGroupEntity where policyid = '" + policyEntity.getPolicyId() + "'")) { - boolean gEntityList = rs.next(); - if (gEntityList) { - return true; - } + SimpleBindings geParams = new SimpleBindings(); + geParams.put("policyEntityId", policyEntity.getPolicyId()); + List<Object> groupobject = commonClassDao.getDataByQuery(groupEntityquery, geParams); + if (!groupobject.isEmpty()) { + return true; } } return false; @@ -458,7 +445,7 @@ public class DeleteHandler { // so we need to fill that in before submitting the group for update ((StdPDPGroup) group).setDirectory(((StdPDPGroup) existingGroup).getDirectory()); try { - acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete"); + acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete", null); } catch (Exception e) { PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: " diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/PushPolicyHandler.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/PushPolicyHandler.java index 4dd87e22f..ed1c57369 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/PushPolicyHandler.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/PushPolicyHandler.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-PAP-REST * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017,2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,68 +17,69 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.pap.xacml.rest.handler; +import com.att.research.xacml.util.XACMLProperties; import java.io.File; import java.net.URI; import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.Query; +import javax.script.SimpleBindings; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - -import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; -import org.onap.policy.pap.xacml.rest.XACMLPapServlet; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.rest.dao.CommonClassDao; import org.onap.policy.rest.jpa.PolicyVersion; import org.onap.policy.xacml.api.pap.OnapPDPGroup; import org.onap.policy.xacml.std.pap.StdPDPPolicy; -import org.onap.policy.common.logging.flexlogger.FlexLogger; -import org.onap.policy.common.logging.flexlogger.Logger; -import com.att.research.xacml.util.XACMLProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +@Component public class PushPolicyHandler { private static final Logger logger = FlexLogger.getLogger(PushPolicyHandler.class); + + private static CommonClassDao commonClassDao; + + @Autowired + public PushPolicyHandler(CommonClassDao commonClassDao) { + PushPolicyHandler.commonClassDao = commonClassDao; + } + + public PushPolicyHandler() { + // Default Constructor + } + /* * Get Active Version. */ public void getActiveVersion(HttpServletRequest request, HttpServletResponse response) { - EntityManager em = null; - if(XACMLPapServlet.getEmf()!=null){ - em = (EntityManager) XACMLPapServlet.getEmf().createEntityManager(); - } - if (em==null){ - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Error creating entity manager with persistence unit: " + XACMLPapServlet.getPersistenceUnit()); - return; - } - String policyScope = request.getParameter("policyScope"); + String policyScope = request.getParameter("policyScope").replace(".", File.separator); String filePrefix = request.getParameter("filePrefix"); String policyName = request.getParameter("policyName"); String pvName = policyScope + File.separator + filePrefix + policyName; int activeVersion = 0; - //Get the Active Version to use in the ID - em.getTransaction().begin(); - Query query = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname"); - query.setParameter("pname", pvName); + // Get the Active Version to use in the ID + String query = "Select p from PolicyVersion p where p.policyName=:pname"; + SimpleBindings params = new SimpleBindings(); + params.put("pname", pvName); @SuppressWarnings("rawtypes") - List result = query.getResultList(); + List result = commonClassDao.getDataByQuery(query, params); PolicyVersion versionEntity = null; if (!result.isEmpty()) { versionEntity = (PolicyVersion) result.get(0); - em.persist(versionEntity); + commonClassDao.save(versionEntity); activeVersion = versionEntity.getActiveVersion(); - em.getTransaction().commit(); } else { PolicyLogger.debug("No PolicyVersion using policyName found"); } - //clean up connection - em.close(); - if (String.valueOf(activeVersion)!=null || !String.valueOf(activeVersion).equalsIgnoreCase("")) { + if (String.valueOf(activeVersion) != null || !String.valueOf(activeVersion).equalsIgnoreCase("")) { response.setStatus(HttpServletResponse.SC_OK); response.addHeader("version", String.valueOf(activeVersion)); } else { diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/SavePolicyHandler.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/SavePolicyHandler.java index 2da84d754..90f8b5a70 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/SavePolicyHandler.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/SavePolicyHandler.java @@ -2,14 +2,14 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,28 +17,25 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.pap.xacml.rest.handler; +import com.att.research.xacml.util.XACMLProperties; import java.io.IOException; import java.util.HashMap; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.ParserConfigurationException; - 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.XACMLPapServlet; import org.onap.policy.pap.xacml.rest.policycontroller.PolicyCreation; import org.onap.policy.rest.adapter.PolicyRestAdapter; import org.onap.policy.utils.PolicyUtils; import org.onap.policy.xacml.std.pap.StdPAPPolicy; import org.xml.sax.SAXException; -import com.att.research.xacml.util.XACMLProperties; - public class SavePolicyHandler { private static final Logger logger = FlexLogger.getLogger(SavePolicyHandler.class); private HashMap<String, String> ErrorHeaders = null; @@ -76,7 +73,7 @@ public class SavePolicyHandler { try { PolicyLogger.info("SavePolicyHandler: Setting parameter values to PolicyAdapter"); policyAdapter = setDataToPolicyAdapter(policy, policyType, apiflag); - + if(!extendedPolicyOptions(policyAdapter, response)){ creation.savePolicy(policyAdapter, response); } @@ -106,7 +103,6 @@ public class SavePolicyHandler { policyAdapter.setPolicyType(policyType); policyAdapter.setDynamicFieldConfigAttributes(policy.getDynamicFieldConfigAttributes()); policyAdapter.setEditPolicy(policy.isEditPolicy()); - policyAdapter.setEntityManagerFactory(XACMLPapServlet.getEmf()); //Config Specific policyAdapter.setConfigName(policy.getConfigName()); //Base and Firewall policyAdapter.setConfigBodyData(policy.getConfigBodyData()); //Base @@ -139,7 +135,7 @@ public class SavePolicyHandler { policyAdapter.setDomainDir(policyAdapter.getPolicyScope()); policyAdapter.setRainydayMap(policy.getTreatments()); policyAdapter.setRawXacmlPolicy(policy.getRawXacmlPolicy()); - + return policyAdapter; } diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java index de5d1cf49..d8a77269c 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java @@ -2,14 +2,14 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,8 +17,10 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.pap.xacml.rest.policycontroller; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.util.Date; import java.util.HashMap; @@ -26,15 +28,12 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.apache.commons.lang.StringUtils; 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.XACMLPapServlet; import org.onap.policy.pap.xacml.rest.components.ActionPolicy; import org.onap.policy.pap.xacml.rest.components.ClosedLoopPolicy; import org.onap.policy.pap.xacml.rest.components.ConfigPolicy; @@ -69,8 +68,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import com.fasterxml.jackson.databind.ObjectMapper; - @RestController @RequestMapping("/") @@ -470,7 +467,7 @@ public class PolicyCreation extends AbstractPolicyCreation{ policyData.setErrorCodeList(errorCodeList); policyData.setTreatmentList(treatmentList); } - newPolicy = new DecisionPolicy(policyData, commonClassDao); + newPolicy = new DecisionPolicy(policyData); } if(newPolicy != null){ @@ -485,7 +482,7 @@ public class PolicyCreation extends AbstractPolicyCreation{ PolicyDBDaoTransaction policyDBDaoTransaction = null; try{ - policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(XACMLPapServlet.getEmf()); + policyDBDao = PolicyDBDao.getPolicyDBDaoInstance(); policyDBDaoTransaction = policyDBDao.getNewTransaction(); policyDBDaoTransaction.createPolicy(newPolicy, policyData.getUserId()); successMap = newPolicy.savePolicies(); @@ -521,7 +518,7 @@ public class PolicyCreation extends AbstractPolicyCreation{ } else { PolicyLogger.info("SafetyCheckerResponse was empty or null."); } - + }else if (successMap.containsKey("invalidAttribute")) { String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Action Attribute"; LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Could not fine " + policyData.getActionAttribute() + " in the ActionPolicyDict table."); @@ -551,7 +548,7 @@ public class PolicyCreation extends AbstractPolicyCreation{ response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.addHeader("error", message); response.addHeader("policyName", policyData.getPolicyName()); - }else { + }else { policyDBDaoTransaction.rollbackTransaction(); body = "error"; status = HttpStatus.INTERNAL_SERVER_ERROR; diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/MetricService.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/MetricService.java index 66fb9acfc..0a539dcbb 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/MetricService.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/MetricService.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP-PAP-REST * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017,2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,37 +17,46 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.pap.xacml.rest.service; +import com.att.research.xacml.api.pap.PDPPolicy; import java.util.HashSet; +import java.util.List; import java.util.Set; - -import javax.persistence.EntityManager; import javax.servlet.http.HttpServletResponse; - import org.json.JSONObject; import org.onap.policy.common.logging.eelf.MessageCodes; import org.onap.policy.common.logging.eelf.PolicyLogger; import org.onap.policy.pap.xacml.rest.XACMLPapServlet; +import org.onap.policy.rest.dao.CommonClassDao; +import org.onap.policy.rest.jpa.PolicyVersion; import org.onap.policy.xacml.api.XACMLErrorConstants; import org.onap.policy.xacml.api.pap.OnapPDPGroup; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -import com.att.research.xacml.api.pap.PDPPolicy; - +@Component public class MetricService { private static String errorMsg = "error"; + private static CommonClassDao commonClassDao; /* * This is a private constructor - * */ + */ private MetricService() { } + @Autowired + private MetricService(CommonClassDao commonClassDao) { + MetricService.commonClassDao = commonClassDao; + } + public static void doGetPolicyMetrics(HttpServletResponse response) { Set<OnapPDPGroup> groups = new HashSet<>(); try { - //get the count of policies on the PDP + // get the count of policies on the PDP if (XACMLPapServlet.getPAPEngine() != null) { groups = XACMLPapServlet.getPAPEngine().getOnapPDPGroups(); } @@ -56,47 +65,36 @@ public class MetricService { Set<PDPPolicy> policies = group.getPolicies(); pdpCount += policies.size(); } - //get the count of policies on the PAP - EntityManager em = null; - if (XACMLPapServlet.getEmf() != null) { - em = XACMLPapServlet.getEmf().createEntityManager(); - } - if (em == null) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + - " Error creating entity manager with persistence unit: " + - XACMLPapServlet.getPersistenceUnit()); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - response.addHeader(errorMsg, "Error creating entity manager with persistence unit"); - return; - } - int papCount = ((Number) em.createNamedQuery("PolicyVersion.findAllCount").getSingleResult()).intValue(); - em.close(); + // get the count of policies on the PAP + List<Object> dataList = commonClassDao.getData(PolicyVersion.class); + int papCount = dataList.size(); int totalCount = pdpCount + papCount; - //create json string for API response + // create json string for API response JSONObject json = new JSONObject(); json.put("papCount", papCount); json.put("pdpCount", pdpCount); json.put("totalCount", totalCount); if (pdpCount > 0 && papCount > 0 && totalCount > 0) { - PolicyLogger - .info("Metrics have been found on the Policy Engine for the number of policies on the PAP and" + - " PDP."); + PolicyLogger.info( + "Metrics have been found on the Policy Engine for the number of policies on the PAP and PDP."); response.setStatus(HttpServletResponse.SC_OK); response.addHeader("successMapKey", "success"); response.addHeader("operation", "getMetrics"); response.addHeader("metrics", json.toString()); + return; } else { String message = - "The policy count on the PAP and PDP is 0. Please check the database and file system to " + - "correct this error."; + "The policy count on the PAP and PDP is 0. Please check the database and file system to correct this error."; response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.addHeader(errorMsg, message); + return; } } catch (Exception e) { String message = XACMLErrorConstants.ERROR_DATA_ISSUE + " Error Querying the Database: " + e.getMessage(); PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPapServlet", " Error Querying the Database."); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.addHeader(errorMsg, message); + return; } } diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/util/JPAUtils.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/util/JPAUtils.java index b9880d8ac..cb9abb9db 100644 --- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/util/JPAUtils.java +++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/util/JPAUtils.java @@ -2,14 +2,14 @@ * ============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. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,50 +20,52 @@ package org.onap.policy.pap.xacml.rest.util; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Query; - +import java.util.List; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; import org.onap.policy.rest.XacmlAdminAuthorization; +import org.onap.policy.rest.dao.CommonClassDao; import org.onap.policy.rest.jpa.GlobalRoleSettings; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -import org.onap.policy.common.logging.flexlogger.FlexLogger; -import org.onap.policy.common.logging.flexlogger.Logger; - +@Component public class JPAUtils { - private static final Logger LOGGER = FlexLogger.getLogger(JPAUtils.class); + private static final Logger LOGGER = FlexLogger.getLogger(JPAUtils.class); - private static EntityManagerFactory emf; + private static CommonClassDao commonClassDao; private static JPAUtils currentInstance = null; + @Autowired + public JPAUtils(CommonClassDao commonClassDao) { + JPAUtils.commonClassDao = commonClassDao; + } + /** - * Get an instance of a JPAUtils. It creates one if it does not exist. - * Only one instance is allowed to be created per server. + * Get an instance of a JPAUtils. It creates one if it does not exist. Only one instance is allowed + * to be created per server. + * * @param emf The EntityFactoryManager to be used for database connections * @return The new instance of JPAUtils or throw exception if the given emf is null. - * @throws IllegalStateException if a JPAUtils has already been constructed. Call getJPAUtilsInstance() to get this. + * @throws IllegalStateException if a JPAUtils has already been constructed. Call + * getJPAUtilsInstance() to get this. */ - public static JPAUtils getJPAUtilsInstance(EntityManagerFactory emf){ - LOGGER.debug("getJPAUtilsInstance(EntityManagerFactory emf) as getJPAUtilsInstance("+emf+") called"); - if(currentInstance == null){ - if(emf != null){ - currentInstance = new JPAUtils(emf); - return currentInstance; - } - throw new IllegalStateException("The EntityManagerFactory is Null"); + public static JPAUtils getJPAUtilsInstance() { + if (currentInstance == null) { + currentInstance = new JPAUtils(); + return currentInstance; } return currentInstance; } - private JPAUtils(EntityManagerFactory emf){ - LOGGER.debug("JPAUtils(EntityManagerFactory emf) as JPAUtils("+emf+") called"); - JPAUtils.emf = emf; + private JPAUtils() { + // Default Constructor } /** - * Returns the lockdown value, in case of exception it is assumed that lockdown functionality - * is not supported and returns false. + * Returns the lockdown value, in case of exception it is assumed that lockdown functionality is not + * supported and returns false. * * * @throws ReadOnlyException @@ -88,15 +90,16 @@ public class JPAUtils { * @throws ReadOnlyException * @throws ConversionException */ - public boolean dbLockdown() - throws IllegalAccessException { + public boolean dbLockdown() throws IllegalAccessException { if (LOGGER.isTraceEnabled()) LOGGER.trace("ENTER"); + List<Object> data = commonClassDao.getData(GlobalRoleSettings.class); - EntityManager em = emf.createEntityManager(); - Query globalRoleSettingsJPA = em.createNamedQuery("GlobalRoleSettings.findAll"); + GlobalRoleSettings globalRoleSettings = null; - GlobalRoleSettings globalRoleSettings = (GlobalRoleSettings) globalRoleSettingsJPA.getSingleResult(); + if (!data.isEmpty()) { + globalRoleSettings = (GlobalRoleSettings) data.get(0); + } if (globalRoleSettings == null) { // this should not happen |