From 3f1933cfe1f5cdb6d3fefdff9248c9d4430849c2 Mon Sep 17 00:00:00 2001 From: Michael Mokry Date: Fri, 1 Dec 2017 11:39:27 -0600 Subject: Modified the code to fix various pushPolicy issues - Added modifications per Pam's review Change-Id: I5d67ee529cbc5245e7d1f8dbec6f2f2d453ce299 Issue-ID: POLICY-486 Signed-off-by: Michael Mokry (cherry picked from commit b6bae924c4a794cd772ac1524089fc8739e310b1) --- .../policy/pap/xacml/rest/XACMLPapServlet.java | 415 ++++++++++++++++----- .../pap/xacml/rest/components/PolicyDBDao.java | 140 ++++++- .../rest/components/PolicyDBDaoTransaction.java | 4 +- .../rest/policycontroller/PolicyCreation.java | 9 + .../services/CreateUpdateDictionaryService.java | 31 +- .../pdp/rest/api/services/ListConfigService.java | 6 +- .../policy/pdp/rest/api/services/PAPServices.java | 3 + .../pdp/rest/api/services/PushPolicyService.java | 36 +- .../policy/pdp/rest/api/utils/PolicyApiUtils.java | 106 ++++++ .../org/onap/policy/xacml/std/pap/StdPDPGroup.java | 2 +- .../PolicyTemplates/FirewallPolicyTemplate.html | 4 +- 11 files changed, 600 insertions(+), 156 deletions(-) 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 4d3fe0653..85d79f74a 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 @@ -305,9 +305,23 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } policyDBDao.setPapEngine((PAPPolicyEngine) XACMLPapServlet.papEngine); if (Boolean.parseBoolean(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_RUN_AUDIT_FLAG))){ + /* + * Auditing the local File System groups to be in sync with the Database + */ + //get an AuditTransaction to lock out all other transactions PolicyDBDaoTransaction auditTrans = policyDBDao.getNewAuditTransaction(); - policyDBDao.auditLocalDatabase(XACMLPapServlet.papEngine); + + 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 + StdPDPGroup group = (StdPDPGroup) papEngine.getDefaultGroup(); + StdPDPGroup updatedGroup = policyDBDao.auditLocalFileSystem(group); + if(updatedGroup!=null) { + papEngine.updateGroup(updatedGroup); + } + LOGGER.info("PapServlet: updated group is " + papEngine.getDefaultGroup().toString()); + //release the transaction lock auditTrans.close(); } @@ -510,14 +524,19 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPost)"); } PolicyDBDaoTransaction pdpTransaction = null; + loggingContext.metricStarted(); try { 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: " + ae.getMessage(); LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, ae); - loggingContext.transactionEnded(); + 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; @@ -526,13 +545,18 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList + " of " + im.getStateManager().getStandbyStatus() + "\n Exception Message: " + se.getMessage(); LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message, se); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPost im startTransaction"); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Failed - See Error.log"); setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); return; } 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. request.getInputStream(); @@ -552,7 +576,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } } + loggingContext.metricStarted(); doACPost(request, response, groupId, loggingContext); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPost doACPost"); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Ended Successfully"); im.endTransaction(); @@ -605,15 +632,18 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } else { String message = "PDP is Unauthorized to Connect to PAP: "+ id; - PolicyLogger.error(MessageCodes.ERROR_PERMISSIONS + " " + message); 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."); PolicyLogger.audit("Transaction Failed - See Error.log"); im.endTransaction(); return; } try{ + loggingContext.metricStarted(); pdpTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPost commitTransaction"); } catch(Exception e){ PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", "Could not commit transaction to put pdp in the database"); } @@ -696,7 +726,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } // 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"); @@ -741,7 +774,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doGet)"); } try { + loggingContext.metricStarted(); XACMLRest.dumpRequest(request); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doGet dumpRequest"); String pathInfo = request.getRequestURI(); LOGGER.info("path info: " + pathInfo); if (pathInfo != null){ @@ -757,7 +793,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } //This im.startTransaction() covers all other Get transactions try { + loggingContext.metricStarted(); im.startTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doGet im startTransaction"); } catch (AdministrativeStateException ae){ String message = "GET interface called for PAP " + papResourceName + " but it has an Administrative" + " state of " + im.getStateManager().getAdminState() @@ -784,8 +823,11 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList if (apiflag!=null) { if(authorizeRequest(request)){ APIRequestHandler apiRequestHandler = new APIRequestHandler(); - try{ + try{ + loggingContext.metricStarted(); apiRequestHandler.doGet(request,response, apiflag); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doGet apiRequestHandler doGet"); }catch(IOException e){ LOGGER.error(e); } @@ -808,7 +850,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList if (groupId != null) { // this is from the Admin Console, so handle separately try{ + loggingContext.metricStarted(); doACGet(request, response, groupId, loggingContext); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doGet doACGet"); } catch(IOException e){ LOGGER.error(e); } @@ -940,7 +985,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doPut)"); } try { + loggingContext.metricStarted(); im.startTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPut im startTransaction"); } catch (AdministrativeStateException | StandbyStatusException e) { String message = "PUT interface called for PAP " + papResourceName; if (e instanceof AdministrativeStateException) { @@ -961,7 +1009,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList return; } + loggingContext.metricStarted(); XACMLRest.dumpRequest(request); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPut dumpRequest"); //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 @@ -977,7 +1028,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList im.endTransaction(); return; } - policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl,policyDBDaoRequestEntityId,policyDBDaoRequestEntityType,policyDBDaoRequestExtraData,this); + loggingContext.metricStarted(); + policyDBDao.handleIncomingHttpNotification(policyDBDaoRequestUrl,policyDBDaoRequestEntityId,policyDBDaoRequestEntityType,policyDBDaoRequestExtraData,this); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPut handle incoming http notification"); response.setStatus(200); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Ended Successfully"); @@ -992,7 +1046,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList if(authorizeRequest(request)){ APIRequestHandler apiRequestHandler = new APIRequestHandler(); try{ + loggingContext.metricStarted(); apiRequestHandler.doPut(request, response, importService); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doPut apiRequestHandler doPut"); }catch(IOException e){ LOGGER.error(e); } @@ -1046,7 +1103,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList im.endTransaction(); return; } + loggingContext.metricStarted(); renameTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet goPut commitTransaction"); response.setStatus(HttpServletResponse.SC_OK); loggingContext.transactionEnded(); PolicyLogger.audit("Transaction Ended Successfully"); @@ -1103,7 +1163,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } // this is from the Admin Console, so handle separately try { + loggingContext.metricEnded(); doACPut(request, response, groupId, loggingContext); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet goPut doACPut"); } catch (IOException e) { LOGGER.error(e); } @@ -1119,7 +1182,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // this request is from the Admin Console SavePolicyHandler savePolicyHandler = SavePolicyHandler.getInstance(); try{ + loggingContext.metricStarted(); savePolicyHandler.doPolicyAPIPut(request, response); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet goPut savePolicyHandler"); } catch (IOException e) { LOGGER.error(e); } @@ -1132,7 +1198,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList if(authorizeRequest(request)){ APIRequestHandler apiRequestHandler = new APIRequestHandler(); try{ + loggingContext.metricStarted(); apiRequestHandler.doPut(request, response, request.getHeader("ClientScope")); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet goPut apiRequestHandler doPut"); } catch (IOException e) { LOGGER.error(e); } @@ -1176,7 +1245,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList PolicyLogger.info("requestID was provided in call to XACMLPapSrvlet (doDelete)"); } try { + loggingContext.metricStarted(); im.startTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doDelete im startTransaction"); } catch (AdministrativeStateException ae){ String message = "DELETE interface called for PAP " + papResourceName + " but it has an Administrative" + " state of " + im.getStateManager().getAdminState() @@ -1198,7 +1270,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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 apiflag = request.getParameter("apiflag"); if (groupId != null) { @@ -1214,18 +1289,24 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } APIRequestHandler apiRequestHandler = new APIRequestHandler(); try { + loggingContext.metricStarted(); apiRequestHandler.doDelete(request, response, loggingContext, apiflag); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doDelete apiRequestHandler doDelete"); } catch (Exception e) { LOGGER.error("Exception Occured"+e); } if(apiRequestHandler.getNewGroup()!=null){ - groupChanged(apiRequestHandler.getNewGroup()); + groupChanged(apiRequestHandler.getNewGroup(), loggingContext); } return; } // this is from the Admin Console, so handle separately try{ + loggingContext.metricStarted(); doACDelete(request, response, groupId, loggingContext); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doDelete doACDelete"); } catch (IOException e) { LOGGER.error(e); } @@ -1317,52 +1398,38 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList */ public void updateGroupsFromAPI(HttpServletRequest request, HttpServletResponse response, String groupId, 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 StdPDPGroup group = (StdPDPGroup) papEngine.getGroup(groupId); + // get the request input stream content into a String String json = null; java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); scanner.useDelimiter("\\A"); json = scanner.hasNext() ? scanner.next() : ""; scanner.close(); - PolicyLogger.info("JSON request from PolicyEngine API: " + json); + + PolicyLogger.info("pushPolicy request from API: " + json); + // convert Object sent as JSON into local object StdPDPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPDPPolicy.class); - Set policies = new HashSet<>(); - if(policy!=null){ - policies.add(policy); - } + //Get the current policies from the Group and Add the new one Set currentPoliciesInGroup = new HashSet<>(); currentPoliciesInGroup = group.getPolicies(); - //If the selected policy is in the group we must remove it because the name is default - Iterator policyIterator = policies.iterator(); - LOGGER.debug("policyIterator....." + policies); - while (policyIterator.hasNext()) { - PDPPolicy selPolicy = policyIterator.next(); - for (PDPPolicy existingPolicy : currentPoliciesInGroup) { - if (existingPolicy.getId().equals(selPolicy.getId())) { - group.removePolicyFromGroup(existingPolicy); - LOGGER.debug("Removing policy: " + existingPolicy); + //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())){ + if (!existingPolicy.getId().equals(policy.getId())) { + group.removePolicy(existingPolicy); + LOGGER.info("Removing policy: " + existingPolicy); break; } } } - //Update the PDP Group after removing old version of policy - Set updatedPoliciesInGroup = new HashSet<>(); - updatedPoliciesInGroup = group.getPolicies(); - //need to remove the policy with default name from group - for (PDPPolicy updatedPolicy : currentPoliciesInGroup) { - if (updatedPolicy.getName().equalsIgnoreCase("default")) { - group.removePolicyFromGroup(updatedPolicy); - break; - } - } - if(updatedPoliciesInGroup!=null){ - policies.addAll(updatedPoliciesInGroup); - } - group.setPolicies(policies); + // Assume that this is an update of an existing PDP Group loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup"); try{ @@ -1372,7 +1439,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList +"group="+group.getId()); throw new PAPException(e.getMessage()); } + + LOGGER.info("Calling updatGroup() with new group"); papEngine.updateGroup(group); + String policyId = "empty"; if(policy!=null){ policyId = policy.getId(); @@ -1381,15 +1451,22 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList response.addHeader("operation", "push"); response.addHeader("policyId", policyId); response.addHeader("groupId", groupId); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Group '" + group.getId() + "' updated"); - } + + LOGGER.info("Group '" + group.getId() + "' updated"); + + loggingContext.metricStarted(); 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); + groupChanged(group, loggingContext); loggingContext.transactionEnded(); - auditLogger.info("Success"); + LOGGER.info("Success"); if (policy != null && ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param")))) { PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance(); @@ -1445,12 +1522,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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; @@ -1460,7 +1539,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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"); @@ -1490,54 +1572,29 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } return; } - // determine the operation needed based on the parameters in the request + + // If the request contains a policyId then we know we are pushing the policy to PDP if (request.getParameter("policyId") != null) { - // Args: group= policy= <= copy file - // copy a policy from the request contents into a file in the group's directory on this machine + if(apiflag!=null){ loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy"); } else { loggingContext.setServiceName("AC:PAP.postPolicy"); } + String policyId = request.getParameter("policyId"); PolicyDBDaoTransaction addPolicyToGroupTransaction = policyDBDao.getNewTransaction(); + StdPDPGroup updatedGroup = null; try { - InputStream is = null; - File temp= null; - if (apiflag != null){ - // get the request content into a String if the request is from API - String json = null; - // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file) - java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); - scanner.useDelimiter("\\A"); - json = scanner.hasNext() ? scanner.next() : ""; - scanner.close(); - LOGGER.info("JSON request from API: " + json); - // convert Object sent as JSON into local object - ObjectMapper mapper = new ObjectMapper(); - Object objectFromJSON = mapper.readValue(json, StdPAPPolicy.class); - StdPAPPolicy policy = (StdPAPPolicy) objectFromJSON; - temp = new File(policy.getLocation()); - is = new FileInputStream(temp); - } else { - is = request.getInputStream(); - } - addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,"XACMLPapServlet.doACPost"); - if (apiflag != null){ - ((StdPDPGroup) group).copyPolicyToFile(policyId,"API", is); - } else { - String name = null; - if (policyId.endsWith(".xml")) { - name = policyId.replace(".xml", ""); - name = name.substring(0, name.lastIndexOf(".")); - } - ((StdPDPGroup) group).copyPolicyToFile(policyId, name, is); - } - if(is!=null && temp!=null){ - is.close(); - temp.delete(); - } + //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; @@ -1553,17 +1610,99 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } return; } + + // Get new transaction to perform updateGroup() + PolicyDBDaoTransaction acPutTransaction = policyDBDao.getNewTransaction(); + try { + /* + * 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. + */ + if(apiflag != null){ + + // get the request content into a String + String json = null; + // read the inputStream into a buffer + java.util.Scanner scanner = new java.util.Scanner(request.getInputStream()); + scanner.useDelimiter("\\A"); + json = scanner.hasNext() ? scanner.next() : ""; + scanner.close(); + LOGGER.info("PushPolicy API request: " + json); + + // convert Object sent as JSON into local object + ObjectMapper mapper = new ObjectMapper(); + Object objectFromJSON = mapper.readValue(json, StdPDPPolicy.class); + StdPDPPolicy policy = (StdPDPPolicy) objectFromJSON; + + // 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","addGroupError"); + 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); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("policy '" + policyId + "' copied to directory for group '" + groupId + "'"); - } + + LOGGER.info("policy '" + policyId + "' copied to directory for group '" + groupId + "'"); loggingContext.transactionEnded(); auditLogger.info("Success"); - PolicyLogger.audit("Transaction Ended Successfully"); + LOGGER.info("Transaction Ended Successfully"); + return; } else if (request.getParameter("default") != null) { // Args: group= default=true <= make default @@ -1575,12 +1714,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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; @@ -1592,11 +1733,14 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // 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"); - PolicyLogger.audit("Transaction Ended Successfully"); + LOGGER.info("Transaction Ended Successfully"); return; } else if (request.getParameter("pdpId") != null) { doACPostTransaction = policyDBDao.getNewTransaction(); @@ -1624,10 +1768,16 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList ((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); + pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); doACPostTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPost commitTransaction"); loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); @@ -1932,10 +2082,16 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // 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); + pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); acPutTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); @@ -2012,11 +2168,17 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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); + groupChanged(group, loggingContext); loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); @@ -2064,7 +2226,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList + "\nfailure with the following exception: " + e); return; } + loggingContext.metricStarted(); deleteTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); response.setStatus(HttpServletResponse.SC_OK); return; } @@ -2107,10 +2272,16 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList // 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); + pdpChanged(pdp, loggingContext); + loggingContext.metricStarted(); removePdpOrGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); @@ -2150,12 +2321,18 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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); + pdpChanged(pdp, loggingContext); } + loggingContext.metricStarted(); removePdpOrGroupTransaction.commitTransaction(); + loggingContext.metricEnded(); + PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction"); loggingContext.transactionEnded(); auditLogger.info("Success"); PolicyLogger.audit("Transaction Ended Successfully"); @@ -2385,7 +2562,21 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList groupChanged(group); } } - + + public void changed(ONAPLoggingContext loggingContext) { + // all PDPs in all groups need to be updated/sync'd + Set groups; + try { + groups = papEngine.getOnapPDPGroups(); + } catch (PAPException e) { + PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "XACMLPapServlet", " getPDPGroups failed"); + throw new IllegalAccessError(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get Groups: " + e); + } + for (OnapPDPGroup group : groups) { + groupChanged(group, loggingContext); + } + } + @Override public void groupChanged(OnapPDPGroup group) { // all PDPs within one group need to be updated/sync'd @@ -2394,8 +2585,15 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList } } + public void groupChanged(OnapPDPGroup group, ONAPLoggingContext loggingContext) { + // all PDPs within one group need to be updated/sync'd + for (OnapPDP pdp : group.getOnapPdps()) { + pdpChanged(pdp, loggingContext); + } + } + @Override - public void pdpChanged(OnapPDP pdp) { + 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. @@ -2404,20 +2602,50 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList t.start(); } } + + public void pdpChanged(OnapPDP pdp, ONAPLoggingContext loggingContext) { + // kick off a thread to do an event notification for each PDP. + // This needs to be on a separate thread so that PDPs that do not respond (down, non-existent, etc) + // do not block the PSP response to the AC, which would freeze the GUI until all PDPs sequentially respond or time-out. + Thread t = new Thread(new UpdatePDPThread(pdp, loggingContext)); + 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)) { + if (!(loggingContext.getRequestID() == null) || (loggingContext.getRequestID() == "")) { + this.requestId = loggingContext.getRequestID(); + } + } + this.loggingContext = loggingContext; + } + public void run() { // send the current configuration to one PDP HttpURLConnection connection = null; // get a new logging context for the thread - ONAPLoggingContext loggingContext = new ONAPLoggingContext(baseLoggingContext); + try { + if (this.loggingContext.equals(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 @@ -2479,7 +2707,10 @@ public class XACMLPapServlet extends HttpServlet implements StdItemSetChangeList 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(); 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 483418c59..7591781ff 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 @@ -32,6 +32,7 @@ import java.io.UnsupportedEncodingException; 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; @@ -68,6 +69,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.onap.policy.common.logging.eelf.MessageCodes; @@ -91,6 +93,7 @@ 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.XACMLPolicyScanner; import org.onap.policy.xacml.util.XACMLPolicyWriter; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -586,16 +589,14 @@ public class PolicyDBDao { } try { if (connection.getResponseCode() == 200) { - logger.info("Received response 200 from pap server on notify"); - //notified = true; + logger.info("PolicyDBDao: NotifyOtherThread received response 200 from pap server on notify"); } else { - logger.warn("connection response code not 200, received: "+connection.getResponseCode()); + 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(); } } @@ -850,9 +851,10 @@ public class PolicyDBDao { 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(policy.getPolicyName())); + ((StdPDPPolicy)(group.getPolicy(pdpPolicyName))).setName(removeExtensionAndVersionFromPolicyName(pdpPolicyName)); try { policyStream.close(); } catch (IOException e) { @@ -862,6 +864,7 @@ public class PolicyDBDao { } } } + logger.info("PolicyDBDao: Adding updated policies to group after notification."); if(didUpdate){ newPolicySet.addAll(group.getPolicies()); group.setPolicies(newPolicySet); @@ -869,6 +872,65 @@ public class PolicyDBDao { return didUpdate; } + + /* + * 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) throws PAPException, PolicyDBException{ + + HashMap currentPolicyMap = new HashMap<>(); + HashSet newPolicyIdSet = new HashSet<>(); + HashSet newPolicySet = new HashSet<>(); + + for(PDPPolicy pdpPolicy : pdpGroup.getPolicies()){ + currentPolicyMap.put(pdpPolicy.getId(), pdpPolicy); + } + + for(PolicyEntity policy : groupentity.getPolicies()){ + String pdpPolicyId = getPdpPolicyName(policy.getPolicyName(), policy.getScope()); + newPolicyIdSet.add(pdpPolicyId); + + if(currentPolicyMap.containsKey(pdpPolicyId)){ + newPolicySet.add(currentPolicyMap.get(pdpPolicyId)); + } else { + + //convert PolicyEntity object to PDPPolicy + String name = pdpPolicyId.replace(".xml", ""); + name = name.substring(0, name.lastIndexOf(".")); + InputStream policyStream = new ByteArrayInputStream(policy.getPolicyData().getBytes()); + pdpGroup.copyPolicyToFile(pdpPolicyId,name,policyStream); + URI location = Paths.get(pdpGroup.getDirectory().toAbsolutePath().toString(), pdpPolicyId).toUri(); + StdPDPPolicy newPolicy = null; + try { + newPolicy = new StdPDPPolicy(pdpPolicyId, true, removeExtensionAndVersionFromPolicyName(pdpPolicyId),location); + newPolicySet.add(newPolicy); + } catch (Exception e) { + logger.debug(e); + PolicyLogger.error("PolicyDBDao: Exception occurred while creating the StdPDPPolicy newPolicy object " + e.getMessage()); + } + + } + + } + + for(String id : currentPolicyMap.keySet()) { + if(!newPolicyIdSet.contains(id)){ + try { + Files.delete(Paths.get(currentPolicyMap.get(id).getLocation())); + } 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()); + } + } + } + + logger.info("PolicyDBDao: Adding new policy set to group to keep filesystem and DB in sync"); + pdpGroup.setPolicies(newPolicySet); + + return pdpGroup; + } + private String removeExtensionAndVersionFromPolicyName(String originalPolicyName) throws PolicyDBException{ return getPolicyNameAndVersionFromPolicyFileName(originalPolicyName)[0]; } @@ -1144,6 +1206,41 @@ public class PolicyDBDao { } } + + public StdPDPGroup auditLocalFileSystem(StdPDPGroup group){ + + logger.info("Starting Local File System group audit"); + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + StdPDPGroup updatedGroup = null; + try { + Query groupQuery = em.createQuery("SELECT g FROM GroupEntity g WHERE g.groupId=:groupId AND g.deleted=:deleted"); + groupQuery.setParameter("groupId", group.getId()); + groupQuery.setParameter("deleted", false); + List groupQueryList = groupQuery.getResultList(); + if(groupQueryList!=null){ + GroupEntity dbgroup = (GroupEntity)groupQueryList.get(0); + updatedGroup = synchronizeGroupPoliciesInFileSystem(group, dbgroup); + } + } catch (PAPException e) { + logger.error(e); + } catch (PolicyDBException e) { + logger.error(e); + } catch (Exception e) { + logger.error(e); + PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PolicyDBDao", "Caught Exception trying to check if group exists groupQuery.getResultList()"); + throw new PersistenceException("Query failed trying to check if group "+group.getId()+" exists"); + } + + em.getTransaction().commit(); + em.close(); + + logger.info("Group was updated during file system audit: " + updatedGroup.toString()); + return updatedGroup; + + } + public void deleteAllGroupTables(){ logger.debug("PolicyDBDao.deleteAllGroupTables() called"); EntityManager em = emf.createEntityManager(); @@ -2688,8 +2785,8 @@ public class PolicyDBDao { } @Override - public void addPolicyToGroup(String groupID, String policyID, String username) throws PolicyDBException { - logger.debug("addPolicyToGroup(String groupID, String policyID, String username) as addPolicyToGroup("+groupID+", "+policyID+","+username+") called"); + 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"); } @@ -2713,6 +2810,7 @@ public class PolicyDBDao { PolicyLogger.error("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); throw new PersistenceException("Somehow, more than one group with the id "+groupID+" were found in the database that are not deleted"); } + //we need to convert the form of the policy id that is used groups into the form that is used //for the database. (com.Config_mypol.1.xml) to (Config_mypol.xml) String[] policyNameScopeAndVersion = getNameScopeAndVersionFromPdpPolicy(policyID); @@ -2735,23 +2833,37 @@ public class PolicyDBDao { PolicyLogger.error("Somehow, more than one policy with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); throw new PersistenceException("Somehow, more than one group with the id "+policyNameScopeAndVersion[0]+" were found in the database that are not deleted"); } + logger.info("PolicyDBDao: Getting group and policy from database"); GroupEntity group = (GroupEntity)groupQueryList.get(0); PolicyEntity policy = (PolicyEntity)policyQueryList.get(0); Iterator 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(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){ - policyIt.remove(); - } - } + while(policyIt.hasNext()){ + PolicyEntity pol = policyIt.next(); + if(getPolicyNameAndVersionFromPolicyFileName(pol.getPolicyName())[0].equals(policyName)){ + policyIt.remove(); + } + } }catch(Exception e){ - logger.debug(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; } } 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 dfe5c70f3..70b8e80f1 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 @@ -29,6 +29,7 @@ import org.onap.policy.rest.jpa.GroupEntity; import org.onap.policy.rest.jpa.PdpEntity; 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; @@ -150,12 +151,13 @@ public interface PolicyDBDaoTransaction { * Add an existing policy to an existing group * @param group The ID of the existing group to add the policy to * @param policyID The ID of an existing policy + * @return * @throws IllegalArgumentException If non-optional parameters are null or empty strings * @throws IllegalStateException If a transaction is already open * @throws PersistenceException If a database error occurs * @throws PolicyDBException */ - public void addPolicyToGroup(String group, String policyID, String username) throws PolicyDBException; + public StdPDPGroup addPolicyToGroup(String group, String policyID, String username) throws PolicyDBException; /** 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 64324d432..2af8a6ee1 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 @@ -193,6 +193,15 @@ public class PolicyCreation extends AbstractPolicyCreation{ return new ResponseEntity(body, status); } }else{ + // if policy does not exist and the request is updatePolicy return error + if(policyData.isEditPolicy()){ + body = "policyNotAvailableForEdit"; + status = HttpStatus.NOT_FOUND; + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + response.addHeader("error", body); + response.addHeader("message", policyData.getPolicyName() + " does not exist on the PAP and cannot be updated."); + return new ResponseEntity(body, status); + } version = 1; if(userId == null){ createdBy = "API"; diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdateDictionaryService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdateDictionaryService.java index 9d2577426..5f6a4fc90 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdateDictionaryService.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdateDictionaryService.java @@ -41,6 +41,7 @@ public class CreateUpdateDictionaryService { private String message = null; private Boolean updateFlag = false; private DictionaryParameters dictionaryParameters = null; + private JsonObject json = null; public CreateUpdateDictionaryService( DictionaryParameters dictionaryParameters, String requestID, @@ -62,6 +63,7 @@ public class CreateUpdateDictionaryService { } this.dictionaryParameters.setRequestID(requestUUID); } + try{ run(); specialCheck(); @@ -105,20 +107,14 @@ public class CreateUpdateDictionaryService { } else { operation = "create"; } - JsonObject json = null; - try{ - json = PolicyApiUtils.stringToJsonObject(dictionaryParameters.getDictionaryJson()); - } catch(JsonException| IllegalStateException e){ - message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper Dictionary JSON object : " + dictionaryParameters.getDictionaryJson(); - LOGGER.error(message, e); - return message; - } + String dictionaryFields = json.toString(); PAPServices papServices = new PAPServices(); return (String) papServices.callPAP(new ByteArrayInputStream(dictionaryFields.getBytes()), new String[] {"operation="+operation, "apiflag=api", "dictionaryType="+dictionaryParameters.getDictionary()}, dictionaryParameters.getRequestID(), "dictionaryItem"); } private boolean getValidation() { + LOGGER.info("Start validating create or update dictionary request."); if(dictionaryParameters==null){ message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Dictionary Parameters are not given."; return false; @@ -134,11 +130,28 @@ public class CreateUpdateDictionaryService { if(dictionaryParameters.getDictionaryJson()==null || dictionaryParameters.getDictionaryJson().isEmpty()){ message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Dictionary JSON given."; return false; - } + } if (updateFlag && "MicroServiceDictionary".equalsIgnoreCase(dictionaryParameters.getDictionary())&& !dictionaryParameters.getDictionaryJson().contains("initialFields")){ message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Mising the required field initialFields."; return false; } + + try{ + json = PolicyApiUtils.stringToJsonObject(dictionaryParameters.getDictionaryJson()); + String result = PolicyApiUtils.validateDictionaryJsonFields(json.getJsonObject("dictionaryFields"), dictionaryParameters.getDictionary()); + + if(!"success".equals(result)) { + message = result; + return false; + } + + }catch(JsonException| IllegalStateException e){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper Dictionary JSON object : " + dictionaryParameters.getDictionaryJson(); + LOGGER.error(message, e); + return false; + } + + LOGGER.info("dictionary API request validation complete and valid."); return true; } diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/ListConfigService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/ListConfigService.java index 26f491963..b1cf79b1e 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/ListConfigService.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/ListConfigService.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import org.onap.policy.api.ConfigRequestParameters; +import org.onap.policy.api.PolicyConfigStatus; import org.onap.policy.common.logging.flexlogger.FlexLogger; import org.onap.policy.common.logging.flexlogger.Logger; import org.onap.policy.pdp.rest.api.models.PolicyConfig; @@ -43,11 +44,12 @@ public class ListConfigService { results = new ArrayList(); status = HttpStatus.OK; for(PolicyConfig policyConfig : policyConfigs){ - if(policyConfig.getPolicyConfigMessage()!=null && policyConfig.getPolicyConfigMessage().contains("PE300")){ + if(policyConfig.getPolicyConfigMessage()!=null && policyConfig.getPolicyConfigMessage().contains("PE300") + && policyConfigs.size()<=1 && policyConfig.getPolicyConfigStatus().equals(PolicyConfigStatus.CONFIG_NOT_FOUND)){ results.add(policyConfig.getPolicyConfigMessage()); status = HttpStatus.BAD_REQUEST; } else { - results.add("Policy Name: " + policyConfig.getPolicyName()); + results.add(policyConfig.getPolicyName()); } } } diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java index f7c175c0c..72d8fdeec 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PAPServices.java @@ -420,6 +420,9 @@ public class PAPServices { + connection.getHeaderField("message") + " Please check the pdpGroup you are requesting to move the policy to."; LOGGER.error(response); + } else if ("policyNotAvailableForEdit".equals(connection.getHeaderField("error"))) { + response = XACMLErrorConstants.ERROR_DATA_ISSUE + + connection.getHeaderField("message"); } } else if (connection.getResponseCode() == 409 && connection.getHeaderField("error") != null) { if ("modelExistsDB".equals(connection.getHeaderField("error"))) { diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java index f2c6c221c..773f0d86a 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java @@ -109,49 +109,15 @@ public class PushPolicyService { } try { LOGGER.debug("StdPDPPolicy object contains: " + selectedPolicy.getId() + ", " + selectedPolicy.getName() + ", " + selectedPolicy.getLocation().toString()); - response = copyPolicy(selectedPolicy, pdpGroup, clientScope, pushPolicyParameters.getRequestID()); + response = (String) papServices.callPAP(selectedPolicy, new String[]{"groupId=" + pdpGroup, "policyId="+selectedPolicy.getId(), "apiflag=api", "operation=POST"}, pushPolicyParameters.getRequestID(), clientScope); } catch (PAPException e) { LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+e.getMessage()); throw new PolicyException(e); } - LOGGER.debug("copyPolicy response: " + response); - if(response.contains("successfully")){ - response = (String) papServices.callPAP(selectedPolicy, new String[]{"groupId=" + pdpGroup, "policyId="+selectedPolicy.getId(), "apiflag=addPolicyToGroup", "operation=PUT"}, pushPolicyParameters.getRequestID(), clientScope); - } LOGGER.debug("Final API response: " + response); return response; } - private String copyPolicy(PDPPolicy policy, String group, String policyType, UUID requestID) throws PAPException { - String response = null; - if (policy == null || group == null) { - throw new PAPException("Null input policy="+policy+" group="+group); - } - try { - StdPAPPolicy location = new StdPAPPolicy(policy.getLocation()); - response = copyFile(policy.getId(), group, location, policyType, requestID); - } catch (Exception e) { - String message = "Unable to PUT policy '" + policy.getId() + "', e:" + e; - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + message, e); - throw new PAPException(message); - } - return response; - } - - private String copyFile(String policyId, String group, StdPAPPolicy location, String clientScope, UUID requestID) throws PAPException { - String response = null; - // send the policy file to the PAP Servlet - PAPServices papService = new PAPServices(); - try { - response = (String) papService.callPAP(location, new String[] {"groupId=" + group, "policyId="+policyId, "apiflag=api", "operation=post"}, requestID, clientScope); - } catch (Exception e) { - String message = "Unable to PUT policy '" + policyId + "', e:" + e; - LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + message, e); - throw new PAPException(message); - } - return response; - } - private boolean getValidation() { // While Validating, extract the required values. if (pushPolicyParameters.getPolicyName() != null diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/utils/PolicyApiUtils.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/utils/PolicyApiUtils.java index cd107d0ba..3e6a3e944 100644 --- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/utils/PolicyApiUtils.java +++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/utils/PolicyApiUtils.java @@ -22,6 +22,7 @@ package org.onap.policy.pdp.rest.api.utils; import java.io.StringReader; import javax.json.Json; +import javax.json.JsonArray; import javax.json.JsonException; import javax.json.JsonObject; import javax.json.JsonReader; @@ -29,13 +30,17 @@ import javax.json.stream.JsonParsingException; import org.onap.policy.common.logging.flexlogger.FlexLogger; import org.onap.policy.common.logging.flexlogger.Logger; +import org.onap.policy.utils.PolicyUtils; +import org.onap.policy.xacml.api.XACMLErrorConstants; import com.google.common.base.CharMatcher; public class PolicyApiUtils { private static Logger LOGGER = FlexLogger.getLogger(PolicyApiUtils.class .getName()); + private static final String SUCCESS = "success"; + public static Boolean validateNONASCIICharactersAndAllowSpaces( String jsonString) { Boolean isValidForm = false; @@ -69,4 +74,105 @@ public class PolicyApiUtils { jsonReader.close(); return object; } + + public static String validateDictionaryJsonFields(JsonObject json, String dictionary) { + + LOGGER.info("Validating DictionaryJsonField values"); + String message; + + if("Action".equals(dictionary.trim())){ + if(json.containsKey("attributeName")){ + if(json.getString("attributeName")==null || json.getString("attributeName").trim().isEmpty()){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Attribute Name provided."; + return message; + } + if(!SUCCESS.equals(PolicyUtils.policySpecialCharValidator(json.getString("attributeName").trim()))){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Attribute Name value."; + return message; + } + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing attributeName key in the dictionaryJson parameter."; + return message; + } + if(json.containsKey("type")){ + if(json.getString("type")==null || json.getString("type").trim().isEmpty()){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Type provided."; + return message; + } + if(!"REST".equals(json.getString("type").trim())){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Type value."; + return message; + } + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing type key in the dictionaryJson parameter."; + return message; + } + if(json.containsKey("method")){ + if(json.getString("method")==null || json.getString("method").trim().isEmpty()){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Method provided."; + return message; + } + if("GET".equals(json.getString("method").trim()) + || "PUT".equals(json.getString("method").trim()) + || "POST".equals(json.getString("method").trim())){ + + message = SUCCESS; + + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Method value."; + return message; + } + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing method key in the dictionaryJson parameter."; + return message; + } + if(json.containsKey("url")){ + if(json.getString("url")==null || json.getString("url").trim().isEmpty()){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No URL provided."; + return message; + } + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing url key in the dictionaryJson parameter."; + return message; + } + if(json.containsKey("body")){ + if(json.getString("body")==null || json.getString("body").trim().isEmpty()){ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Body provided."; + return message; + } + }else{ + message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing body key in the dictionaryJson parameter."; + return message; + } + if(json.containsKey("headers")){ + JsonArray array = json.getJsonArray("headers"); + + for (int i = 0;i
- @@ -109,7 +109,7 @@ ng-disabled="temp.policy.readOnly" ng-click="validatePolicy(temp.policy);">Validate
-- cgit 1.2.3-korg