- /**
- * 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");
-
- 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 = 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");
- return;
- } 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");
- return;
- }
- } 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());
- return;
- }
- }
-
- /**
- * 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());
- return;
- }
- }
-
- /**
- * 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");
- 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("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");
- 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("Transaction Failed - See Error.log");
- 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("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");
- return;
- }
- } 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());
- return;
- }
- }
-
- /**
- * 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");
- return;
- } 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");
- 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("Transaction Failed - See Error.log");
- 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
- 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");
- return;
- }
- } 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());
- return;
- }
- }
-
- /**
- * Heartbeat thread - periodically check on PDPs' status
- *
- * Heartbeat with all known PDPs.
- *
- * Implementation note:
- *
- * The PDPs are contacted Sequentially, not in Parallel.
- *
- * If we did this in parallel using multiple threads we would simultaneously use
- * - 1 thread and
- * - 1 connection
- * for EACH PDP.
- * This could become a resource problem since we already use multiple threads and connections for updating the PDPs
- * when user changes occur.
- * Using separate threads can also make it tricky dealing with timeouts on PDPs that are non-responsive.
- *
- * The Sequential operation does a heartbeat request to each PDP one at a time.
- * This has the flaw that any PDPs that do not respond will hold up the entire heartbeat sequence until they timeout.
- * If there are a lot of non-responsive PDPs and the timeout is large-ish (the default is 20 seconds)
- * it could take a long time to cycle through all of the PDPs.
- * That means that this may not notice a PDP being down in a predictable time.
- */
- private class Heartbeat implements Runnable {
- private PAPPolicyEngine papEngine;
- private Set<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();
- }
- }
- }
-