2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pap.xacml.rest;
23 import com.att.research.xacml.api.pap.PAPException;
24 import com.fasterxml.jackson.databind.ObjectMapper;
26 import java.io.IOException;
27 import java.io.UnsupportedEncodingException;
28 import java.net.URLDecoder;
29 import java.nio.file.Files;
30 import java.nio.file.Paths;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Scanner;
37 import javax.servlet.ServletException;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
41 import org.onap.policy.common.logging.OnapLoggingContext;
42 import org.onap.policy.common.logging.eelf.MessageCodes;
43 import org.onap.policy.common.logging.eelf.PolicyLogger;
44 import org.onap.policy.common.logging.flexlogger.FlexLogger;
45 import org.onap.policy.common.logging.flexlogger.Logger;
46 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao;
47 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
48 import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler;
49 import org.onap.policy.xacml.api.XACMLErrorConstants;
50 import org.onap.policy.xacml.api.pap.OnapPDP;
51 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
52 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
53 import org.onap.policy.xacml.std.pap.StdPDP;
54 import org.onap.policy.xacml.std.pap.StdPDPGroup;
55 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
57 public class ConsoleAndApiService {
59 private static final Logger LOGGER = FlexLogger.getLogger(ConsoleAndApiService.class);
60 private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
61 private static final String ADD_GROUP_ERROR = "addGroupError";
62 private static final String REGEX = "[0-9a-zA-Z._, ]*";
63 private static final String TRANSACTIONFAILED = "Transaction Failed - See Error.log";
64 private static final String PAPSERVLETDOACPOST = "XACMLPapServlet.doACPost";
65 private static final String ACPOSTCOMMITTRANS = "XACMLPapServlet doACPost commitTransaction";
66 private static final String XACMLPAPSERVLET = "XACMLPapServlet";
67 private static final String SUCCESS = "Success";
68 private static final String ERROR = "error";
69 private static final String MESSAGE = "message";
70 private static final String POLICYID = "policyId";
71 private static final String TRANSENDED = "Transaction Ended Successfully";
74 * Requests from the Admin Console for operations not on single specific objects.
76 * @param request Servlet request
77 * @param response Servlet response
78 * @param groupId the group id
79 * @param loggingContext the logging context
80 * @param papEngine the pap engine
81 * @throws ServletException the servlet exception
82 * @throws IOException Signals that an I/O exception has occurred.
84 public void doAcPost(HttpServletRequest request, HttpServletResponse response, String groupId,
85 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
86 PolicyDBDaoTransaction doAcPostTransaction = null;
88 String groupName = request.getParameter("groupName");
89 String groupDescription = request.getParameter("groupDescription");
90 String apiflag = request.getParameter("apiflag");
91 String userId = request.getParameter("userId");
92 if (groupName != null && groupDescription != null) {
93 // Args: group=<groupId> groupName=<name>
94 // groupDescription=<description> <= create a new group
95 loggingContext.setServiceName("AC:PAP.createGroup");
96 String unescapedName = null;
97 String unescapedDescription = null;
99 unescapedName = URLDecoder.decode(groupName, "UTF-8");
100 unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
101 } catch (UnsupportedEncodingException e) {
104 PolicyDBDaoTransaction newGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
106 newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName,
107 unescapedDescription, PAPSERVLETDOACPOST);
108 papEngine.newGroup(unescapedName, unescapedDescription);
109 loggingContext.metricStarted();
110 newGroupTransaction.commitTransaction();
111 loggingContext.metricEnded();
112 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
113 } catch (Exception e) {
114 newGroupTransaction.rollbackTransaction();
115 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
116 " Unable to create new group");
117 loggingContext.transactionEnded();
118 PolicyLogger.audit(TRANSACTIONFAILED);
119 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
120 "Unable to create new group '" + groupId + "'");
123 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
124 if (LOGGER.isDebugEnabled()) {
125 LOGGER.debug("New Group '" + groupId + "' created");
127 auditLogger.info(SUCCESS);
128 PolicyLogger.audit(TRANSENDED);
131 // for all remaining POST operations the group must exist before the
132 // operation can be done
133 OnapPDPGroup group = null;
135 group = papEngine.getGroup(groupId);
136 } catch (PAPException e) {
140 String message = "Unknown groupId '" + groupId + "'";
141 // for fixing Header Manipulation of Fortify issue
142 if (!message.matches(REGEX)) {
143 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
144 response.addHeader(ERROR, ADD_GROUP_ERROR);
145 response.addHeader(MESSAGE, "GroupId Id is not valid");
148 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
149 loggingContext.transactionEnded();
150 PolicyLogger.audit(TRANSACTIONFAILED);
151 if (apiflag != null) {
152 response.addHeader(ERROR, "unknownGroupId");
153 response.addHeader("operation", "push");
154 response.addHeader(MESSAGE, message);
155 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
157 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
162 // If the request contains a policyId then we know we are pushing
164 if (request.getParameter(POLICYID) != null) {
165 String policyName = request.getParameter(POLICYID);
166 List<String> policyIdList = Arrays.asList(policyName.split(","));
168 loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
169 LOGGER.info("PushPolicy Request - " + policyName + ", UserId - " + userId);
171 StdPDPGroup updatedGroup = null;
172 StdPDPPolicy policyForSafetyCheck = new StdPDPPolicy();
173 for (String policyId : policyIdList) {
174 PolicyDBDaoTransaction addPolicyToGroupTransaction =
175 XACMLPapServlet.getPolicyDbDao().getNewTransaction();
177 // Copying the policy to the file system and updating groups
179 LOGGER.info("PapServlet: calling PolicyDBDao.addPolicyToGroup()");
180 updatedGroup = addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,
181 PAPSERVLETDOACPOST, userId);
182 loggingContext.metricStarted();
183 addPolicyToGroupTransaction.commitTransaction();
184 loggingContext.metricEnded();
185 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
186 LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed");
188 if (policyId.contains("Config_MS_") || policyId.contains("BRMS_Param")) {
189 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
190 policyForSafetyCheck.setId(policyId);
191 if (pushPolicyHandler.preSafetyCheck(policyForSafetyCheck,
192 XACMLPapServlet.getConfigHome())) {
193 LOGGER.debug("Precheck Successful.");
197 // delete temporary policy file from the bin directory
198 Files.deleteIfExists(Paths.get(policyId));
200 } catch (Exception e) {
201 addPolicyToGroupTransaction.rollbackTransaction();
202 String message = "Policy '" + policyName + "' not copied to group '" + groupId + "': " + e;
203 // for fixing Header Manipulation of Fortify issue
204 if (!message.matches(REGEX)) {
205 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
206 response.addHeader(ERROR, ADD_GROUP_ERROR);
207 response.addHeader(MESSAGE, "Policy Id is not valid");
210 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
211 loggingContext.transactionEnded();
212 PolicyLogger.audit(TRANSACTIONFAILED);
213 if (apiflag != null) {
214 response.addHeader(ERROR, "policyCopyError");
215 response.addHeader(MESSAGE, message);
216 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
218 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
225 * If request comes from the API we need to run the PolicyDBDao updateGroup() to notify other paps of
226 * the change. The GUI does this from the POLICY-SDK-APP code.
229 // Get new transaction to perform updateGroup()
230 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
232 // Assume that this is an update of an existing PDP
234 loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
236 acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut", userId);
237 } catch (Exception e) {
238 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
239 " Error occurred when notifying PAPs of a group change: " + e);
240 throw new PAPException(e.getMessage());
243 LOGGER.info("Calling updatGroup() with new group");
244 papEngine.updateGroup(updatedGroup);
246 LOGGER.info("Group - '" + updatedGroup.getId() + "' updated");
248 // Commit transaction to send notification to other PAPs
249 loggingContext.metricStarted();
250 acPutTransaction.commitTransaction();
251 loggingContext.metricEnded();
252 PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
253 // Group changed to send notification to PDPs, which
254 // might include changing the policies
255 getPapInstance().groupChanged(updatedGroup, loggingContext);
256 loggingContext.transactionEnded();
257 LOGGER.info(SUCCESS);
258 } catch (Exception e) {
259 acPutTransaction.rollbackTransaction();
260 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " API PUT exception");
261 loggingContext.transactionEnded();
262 PolicyLogger.audit(TRANSACTIONFAILED);
263 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW
264 + "Exception occurred when updating the group from API.";
265 LOGGER.error(message);
266 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
267 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
268 response.addHeader(ERROR, ADD_GROUP_ERROR);
269 response.addHeader(MESSAGE, message);
272 // policy file copied ok and the Group was updated on the PDP
273 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
274 response.addHeader("operation", "push");
275 response.addHeader(POLICYID, policyName);
276 response.addHeader("groupId", groupId);
278 LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'");
279 loggingContext.transactionEnded();
280 auditLogger.info(SUCCESS);
281 LOGGER.info(TRANSENDED);
284 } else if (request.getParameter("default") != null) {
285 // Args: group=<groupId> default=true <= make default
286 // change the current default group to be the one identified in
288 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
289 // This is a POST operation rather than a PUT "update group"
290 // because of the side-effect that the current default group is
292 // It should never be the case that multiple groups are
293 // currently marked as the default, but protect against that
295 PolicyDBDaoTransaction setDefaultGroupTransaction =
296 XACMLPapServlet.getPolicyDbDao().getNewTransaction();
298 setDefaultGroupTransaction.changeDefaultGroup(group, PAPSERVLETDOACPOST);
299 papEngine.setDefaultGroup(group);
300 loggingContext.metricStarted();
301 setDefaultGroupTransaction.commitTransaction();
302 loggingContext.metricEnded();
303 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
304 } catch (Exception e) {
305 setDefaultGroupTransaction.rollbackTransaction();
306 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " Unable to set group");
307 loggingContext.transactionEnded();
308 PolicyLogger.audit(TRANSACTIONFAILED);
309 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
310 "Unable to set group '" + groupId + "' to default");
313 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
314 if (LOGGER.isDebugEnabled()) {
315 LOGGER.debug("Group- '" + groupId + "' set to be default");
317 auditLogger.info(SUCCESS);
318 LOGGER.info(TRANSENDED);
320 } else if (request.getParameter("pdpId") != null) {
321 doAcPostTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
322 // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
323 loggingContext.setServiceName("AC:PAP.movePDP");
324 String pdpId = request.getParameter("pdpId");
325 OnapPDP pdp = papEngine.getPDP(pdpId);
326 OnapPDPGroup originalGroup = papEngine.getPDPGroup(pdp);
328 doAcPostTransaction.movePdp(pdp, group, PAPSERVLETDOACPOST);
329 } catch (Exception e) {
330 doAcPostTransaction.rollbackTransaction();
331 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
332 " Error while moving pdp in the database: " + "pdp=" + pdp.getId() + ",to group="
334 throw new PAPException(e.getMessage());
336 papEngine.movePDP(pdp, group);
337 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
338 if (LOGGER.isDebugEnabled()) {
340 "PDP - '" + pdp.getId() + "' moved to group - '" + group.getId() + "' set to be default");
342 // update the status of both the original group and the new one
343 ((StdPDPGroup) originalGroup).resetStatus();
344 ((StdPDPGroup) group).resetStatus();
345 // Need to notify the PDP that it's config may have changed
346 getPapInstance().pdpChanged(pdp, loggingContext);
347 loggingContext.metricStarted();
348 doAcPostTransaction.commitTransaction();
349 loggingContext.metricEnded();
350 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
351 loggingContext.transactionEnded();
352 auditLogger.info(SUCCESS);
353 PolicyLogger.audit(TRANSENDED);
356 } catch (PAPException e) {
357 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC POST exception");
358 loggingContext.transactionEnded();
359 PolicyLogger.audit(TRANSACTIONFAILED);
360 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
366 * Requests from the Admin Console to GET info about the Groups and PDPs.
368 * @param request the request
369 * @param response the response
370 * @param groupId the group id
371 * @param loggingContext the logging context
372 * @param papEngine the pap engine
373 * @throws IOException Signals that an I/O exception has occurred.
375 public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId,
376 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
378 String parameterDefault = request.getParameter("default");
379 String pdpId = request.getParameter("pdpId");
380 String pdpGroup = request.getParameter("getPDPGroup");
381 if ("".equals(groupId)) {
382 // request IS from AC but does not identify a group by name
383 if (parameterDefault != null) {
384 // Request is for the Default group (whatever its id)
385 loggingContext.setServiceName("AC:PAP.getDefaultGroup");
386 OnapPDPGroup group = papEngine.getDefaultGroup();
387 // convert response object to JSON and include in the
389 mapperWriteValue(new ObjectMapper(), response, group);
390 if (LOGGER.isDebugEnabled()) {
391 LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
393 response.setStatus(HttpServletResponse.SC_OK);
394 response.setHeader("content-type", "application/json");
396 response.getOutputStream().close();
397 } catch (IOException e) {
400 loggingContext.transactionEnded();
401 auditLogger.info(SUCCESS);
402 PolicyLogger.audit(TRANSENDED);
404 } else if (pdpId != null) {
405 // Request is related to a PDP
406 if (pdpGroup == null) {
407 // Request is for the (unspecified) group containing a
409 loggingContext.setServiceName("AC:PAP.getPDP");
412 pdp = papEngine.getPDP(pdpId);
413 } catch (PAPException e) {
416 // convert response object to JSON and include in the
418 mapperWriteValue(new ObjectMapper(), response, pdp);
419 if (LOGGER.isDebugEnabled()) {
420 LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
422 response.setStatus(HttpServletResponse.SC_OK);
423 response.setHeader("content-type", "application/json");
425 response.getOutputStream().close();
426 } catch (IOException e) {
429 loggingContext.transactionEnded();
430 auditLogger.info(SUCCESS);
431 PolicyLogger.audit(TRANSENDED);
434 // Request is for the group containing a given PDP
435 loggingContext.setServiceName("AC:PAP.getGroupForPDP");
436 OnapPDPGroup group = null;
438 OnapPDP pdp = papEngine.getPDP(pdpId);
439 group = papEngine.getPDPGroup(pdp);
440 } catch (PAPException e) {
443 // convert response object to JSON and include in the
445 mapperWriteValue(new ObjectMapper(), response, group);
446 if (LOGGER.isDebugEnabled()) {
447 LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
449 response.setStatus(HttpServletResponse.SC_OK);
450 response.setHeader("content-type", "application/json");
452 response.getOutputStream().close();
453 } catch (IOException e) {
456 loggingContext.transactionEnded();
457 auditLogger.info(SUCCESS);
458 PolicyLogger.audit(TRANSENDED);
462 // request is for top-level properties about all groups
463 loggingContext.setServiceName("AC:PAP.getAllGroups");
464 Set<OnapPDPGroup> groups = null;
466 groups = papEngine.getOnapPDPGroups();
467 } catch (PAPException e) {
468 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
469 loggingContext.transactionEnded();
470 PolicyLogger.audit(TRANSACTIONFAILED);
471 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
474 // convert response object to JSON and include in the
476 mapperWriteValue(new ObjectMapper(), response, groups);
477 if (LOGGER.isDebugEnabled()) {
478 LOGGER.debug("GET All groups req");
480 response.setStatus(HttpServletResponse.SC_OK);
481 response.setHeader("content-type", "application/json");
483 response.getOutputStream().close();
484 } catch (IOException e) {
487 loggingContext.transactionEnded();
488 auditLogger.info(SUCCESS);
489 PolicyLogger.audit(TRANSENDED);
493 // for all other GET operations the group must exist before the
494 // operation can be done
495 OnapPDPGroup group = null;
497 group = papEngine.getGroup(groupId);
498 } catch (PAPException e) {
502 String message = "Unknown groupId '" + groupId + "'";
503 // for fixing Header Manipulation of Fortify issue
504 if (!message.matches(REGEX)) {
505 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
506 response.addHeader(ERROR, ADD_GROUP_ERROR);
507 response.addHeader(MESSAGE, "Group Id is not valid");
510 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
511 loggingContext.transactionEnded();
512 PolicyLogger.audit(TRANSACTIONFAILED);
513 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
516 // Figure out which request this is based on the parameters
517 String policyId = request.getParameter(POLICYID);
518 if (policyId != null) {
520 loggingContext.setServiceName("AC:PAP.getPolicy");
521 // convert response object to JSON and include in the response
522 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
523 loggingContext.transactionEnded();
524 PolicyLogger.audit(TRANSACTIONFAILED);
525 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
527 // No other parameters, so return the identified Group
528 loggingContext.setServiceName("AC:PAP.getGroup");
529 // convert response object to JSON and include in the response
530 mapperWriteValue(new ObjectMapper(), response, group);
531 if (LOGGER.isDebugEnabled()) {
532 LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
534 response.setStatus(HttpServletResponse.SC_OK);
535 response.setHeader("content-type", "application/json");
537 response.getOutputStream().close();
538 } catch (IOException e) {
541 loggingContext.transactionEnded();
542 auditLogger.info(SUCCESS);
543 PolicyLogger.audit(TRANSENDED);
546 // Currently there are no other GET calls from the AC.
547 // The AC uses the "GET All Groups" operation to fill its local
548 // cache and uses that cache for all other GETs without calling the
550 // Other GETs that could be called:
551 // Specific Group (groupId=<groupId>)
552 // A Policy (groupId=<groupId> policyId=<policyId>)
553 // A PDP (groupId=<groupId> pdpId=<pdpId>)
554 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
555 loggingContext.transactionEnded();
556 PolicyLogger.audit(TRANSACTIONFAILED);
557 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
558 } catch (PAPException e) {
559 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
560 loggingContext.transactionEnded();
561 PolicyLogger.audit(TRANSACTIONFAILED);
562 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
568 * Requests from the Admin Console to create new items or update existing ones.
570 * @param request the request
571 * @param response the response
572 * @param groupId the group id
573 * @param loggingContext the logging context
574 * @param papEngine the pap engine
575 * @throws IOException Signals that an I/O exception has occurred.
577 public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId,
578 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
579 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
581 String userId = request.getParameter("userId");
582 // for PUT operations the group may or may not need to exist before
583 // the operation can be done
584 OnapPDPGroup group = papEngine.getGroup(groupId);
585 // determine the operation needed based on the parameters in the
587 // for remaining operations the group must exist before the
588 // operation can be done
590 String message = "Unknown groupId '" + groupId + "'";
591 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
592 loggingContext.transactionEnded();
593 PolicyLogger.audit(TRANSACTIONFAILED);
594 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
595 acPutTransaction.rollbackTransaction();
598 if (request.getParameter("policy") != null) {
599 // group=<groupId> policy=<policyId> contents=policy file <=
600 // Create new policy file in group dir, or replace it if it
601 // already exists (do not touch properties)
602 loggingContext.setServiceName("AC:PAP.putPolicy");
603 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
604 + " PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
605 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
606 loggingContext.transactionEnded();
607 PolicyLogger.audit(TRANSACTIONFAILED);
608 auditLogger.info(SUCCESS);
609 PolicyLogger.audit(TRANSENDED);
610 acPutTransaction.rollbackTransaction();
612 } else if (request.getParameter("pdpId") != null) {
613 // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP
614 // or Update an Existing one
615 String pdpId = request.getParameter("pdpId");
616 if (papEngine.getPDP(pdpId) == null) {
617 loggingContext.setServiceName("AC:PAP.createPDP");
619 loggingContext.setServiceName("AC:PAP.updatePDP");
621 // get the request content into a String
623 // read the inputStream into a buffer (trick found online scans
624 // entire input looking for end-of-file)
626 Scanner scanner = new Scanner(request.getInputStream());
627 scanner.useDelimiter("\\A");
628 json = scanner.hasNext() ? scanner.next() : "";
630 } catch (IOException e) {
633 LOGGER.info("JSON request from AC: " + json);
634 // convert Object sent as JSON into local object
635 ObjectMapper mapper = new ObjectMapper();
636 Object objectFromJson = null;
638 objectFromJson = mapper.readValue(json, StdPDP.class);
639 } catch (Exception e) {
642 if (pdpId == null || objectFromJson == null || !(objectFromJson instanceof StdPDP)
643 || ((StdPDP) objectFromJson).getId() == null
644 || !((StdPDP) objectFromJson).getId().equals(pdpId)) {
645 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId
646 + " objectFromJSON=" + objectFromJson);
647 loggingContext.transactionEnded();
648 PolicyLogger.audit(TRANSACTIONFAILED);
649 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
650 "Bad input pdpid for object:" + objectFromJson);
652 StdPDP pdp = (StdPDP) objectFromJson;
654 OnapPDP origPdp = null;
656 origPdp = papEngine.getPDP(pdpId);
657 } catch (PAPException e) {
660 if (origPdp == null) {
661 // this is a request to create a new PDP object
663 acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
664 pdp.getDescription(), pdp.getJmxPort(), "XACMLPapServlet.doACPut");
665 papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
666 } catch (Exception e) {
667 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
668 " Error while adding pdp to group in the database: " + "pdp=" + (pdp.getId())
669 + ",to group=" + group.getId());
670 throw new PAPException(e.getMessage());
673 // this is a request to update the pdp
675 acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
676 papEngine.updatePDP(pdp);
677 } catch (Exception e) {
678 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
679 " Error while updating pdp in the database: " + "pdp=" + pdp.getId());
680 throw new PAPException(e.getMessage());
683 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
684 if (LOGGER.isDebugEnabled()) {
685 LOGGER.debug("PDP '" + pdpId + "' created/updated");
687 // adjust the group's state including the new PDP
688 ((StdPDPGroup) group).resetStatus();
689 // this might affect the PDP, so notify it of the change
690 getPapInstance().pdpChanged(pdp, loggingContext);
691 loggingContext.metricStarted();
692 acPutTransaction.commitTransaction();
693 loggingContext.metricEnded();
694 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
695 loggingContext.transactionEnded();
696 auditLogger.info(SUCCESS);
697 PolicyLogger.audit(TRANSENDED);
701 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, XACMLPAPSERVLET,
702 " Error while adding pdp to group in the database: " + "pdp=null" + ",to group="
704 throw new PAPException("PDP is null");
705 } catch (Exception e) {
706 throw new PAPException("PDP is null" + e.getMessage() + e);
709 } else if (request.getParameter("pipId") != null) {
710 // group=<groupId> pipId=<pipEngineId> contents=pip properties
711 // <= add a PIP to pip config, or replace it if it already
712 // exists (lenient operation)
713 loggingContext.setServiceName("AC:PAP.putPIP");
714 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
715 loggingContext.transactionEnded();
716 PolicyLogger.audit(TRANSACTIONFAILED);
717 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
718 acPutTransaction.rollbackTransaction();
721 // Assume that this is an update of an existing PDP Group
722 // ARGS: group=<groupId> <= Update an Existing Group
723 loggingContext.setServiceName("AC:PAP.updateGroup");
724 // get the request content into a String
726 // read the inputStream into a buffer (trick found online scans
727 // entire input looking for end-of-file)
729 Scanner scanner = new Scanner(request.getInputStream());
730 scanner.useDelimiter("\\A");
731 json = scanner.hasNext() ? scanner.next() : "";
733 } catch (IOException e) {
736 LOGGER.info("JSON request from AC: " + json);
737 // convert Object sent as JSON into local object
738 ObjectMapper mapper = new ObjectMapper();
739 Object objectFromJson = null;
741 objectFromJson = mapper.readValue(json, StdPDPGroup.class);
742 } catch (Exception e) {
745 if (objectFromJson == null || !(objectFromJson instanceof StdPDPGroup)
746 || !((StdPDPGroup) objectFromJson).getId().equals(group.getId())) {
747 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id="
748 + group.getId() + " objectFromJSON=" + objectFromJson);
749 loggingContext.transactionEnded();
750 PolicyLogger.audit(TRANSACTIONFAILED);
751 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
752 "Bad input id for object:" + objectFromJson);
754 // The Path on the PAP side is not carried on the RESTful
755 // interface with the AC
756 // (because it is local to the PAP)
757 // so we need to fill that in before submitting the group for
759 if (objectFromJson != null) {
760 ((StdPDPGroup) objectFromJson).setDirectory(((StdPDPGroup) group).getDirectory());
763 if ("delete".equals(((StdPDPGroup) objectFromJson).getOperation())) {
764 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doDelete", userId);
766 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doACPut", userId);
768 } catch (Exception e) {
769 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
770 + "group=" + group.getId());
772 throw new PAPException(e.getMessage());
775 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
776 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJson;
777 if (pushPolicyHandler.preSafetyCheck(updatedGroup, XACMLPapServlet.getConfigHome())) {
778 LOGGER.debug("Precheck Successful.");
781 papEngine.updateGroup((StdPDPGroup) objectFromJson);
782 } catch (PAPException e) {
785 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
786 if (LOGGER.isDebugEnabled()) {
787 LOGGER.debug("Group '" + group.getId() + "' updated");
789 loggingContext.metricStarted();
790 acPutTransaction.commitTransaction();
791 loggingContext.metricEnded();
792 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
793 // Group changed, which might include changing the policies
794 getPapInstance().groupChanged(group, loggingContext);
795 loggingContext.transactionEnded();
796 auditLogger.info(SUCCESS);
797 PolicyLogger.audit(TRANSENDED);
800 } catch (PAPException e) {
802 acPutTransaction.rollbackTransaction();
803 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC PUT exception");
804 loggingContext.transactionEnded();
805 PolicyLogger.audit(TRANSACTIONFAILED);
806 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
812 * Requests from the Admin Console to delete/remove items.
814 * @param request the request
815 * @param response the response
816 * @param groupId the group id
817 * @param loggingContext the logging context
818 * @param papEngine the pap engine
819 * @throws IOException Signals that an I/O exception has occurred.
821 public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
822 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
823 PolicyDBDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
825 // for all DELETE operations the group must exist before the
826 // operation can be done
827 loggingContext.setServiceName("AC:PAP.delete");
828 OnapPDPGroup group = papEngine.getGroup(groupId);
830 String message = "Unknown groupId '" + groupId + "'";
831 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
832 loggingContext.transactionEnded();
833 PolicyLogger.audit(TRANSACTIONFAILED);
834 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId + "'");
835 removePdpOrGroupTransaction.rollbackTransaction();
838 // determine the operation needed based on the parameters in the
840 if (request.getParameter("policy") != null) {
841 // group=<groupId> policy=<policyId> [delete=<true|false>] <=
842 // delete policy file from group
843 loggingContext.setServiceName("AC:PAP.deletePolicy");
844 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
845 loggingContext.transactionEnded();
846 PolicyLogger.audit(TRANSACTIONFAILED);
847 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
848 removePdpOrGroupTransaction.rollbackTransaction();
850 } else if (request.getParameter("pdpId") != null) {
851 // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
852 String pdpId = request.getParameter("pdpId");
853 OnapPDP pdp = papEngine.getPDP(pdpId);
854 removePdpFromGroup(removePdpOrGroupTransaction, pdp, papEngine);
855 // adjust the status of the group, which may have changed when
856 // we removed this PDP
857 ((StdPDPGroup) group).resetStatus();
858 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
859 // update the PDP and tell it that it has NO Policies (which
860 // prevents it from serving PEP Requests)
861 getPapInstance().pdpChanged(pdp, loggingContext);
862 loggingContext.metricStarted();
863 removePdpOrGroupTransaction.commitTransaction();
864 loggingContext.metricEnded();
865 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
866 loggingContext.transactionEnded();
867 auditLogger.info(SUCCESS);
868 PolicyLogger.audit(TRANSENDED);
870 } else if (request.getParameter("pipId") != null) {
871 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for
873 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
874 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
875 loggingContext.transactionEnded();
876 PolicyLogger.audit(TRANSACTIONFAILED);
877 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
878 removePdpOrGroupTransaction.rollbackTransaction();
881 // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>
882 // <= delete a group and move all its PDPs to the given group
883 String moveToGroupId = request.getParameter("movePDPsToGroupId");
884 OnapPDPGroup moveToGroup = null;
885 if (moveToGroupId != null) {
887 moveToGroup = papEngine.getGroup(moveToGroupId);
888 } catch (PAPException e) {
892 // get list of PDPs in the group being deleted so we can notify
893 // them that they got changed
894 Set<OnapPDP> movedPdps = new HashSet<>();
895 movedPdps.addAll(group.getOnapPdps());
896 // do the move/remove
897 deleteGroup(removePdpOrGroupTransaction, group, moveToGroup, papEngine);
898 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
899 // notify any PDPs in the removed set that their config may have
901 for (OnapPDP pdp : movedPdps) {
902 getPapInstance().pdpChanged(pdp, loggingContext);
904 loggingContext.metricStarted();
905 removePdpOrGroupTransaction.commitTransaction();
906 loggingContext.metricEnded();
907 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
908 loggingContext.transactionEnded();
909 auditLogger.info(SUCCESS);
910 PolicyLogger.audit(TRANSENDED);
913 } catch (PAPException e) {
914 removePdpOrGroupTransaction.rollbackTransaction();
915 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC DELETE exception");
916 loggingContext.transactionEnded();
917 PolicyLogger.audit(TRANSACTIONFAILED);
918 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
923 private void deleteGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group,
924 OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException {
926 removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete");
927 papEngine.removeGroup(group, moveToGroup);
928 } catch (Exception e) {
929 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, XACMLPAPSERVLET,
930 " Failed to delete PDP Group. Exception");
931 throw new PAPException(e.getMessage());
935 private void removePdpFromGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp,
936 PAPPolicyEngine papEngine) throws PAPException {
938 removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
939 papEngine.removePDP(pdp);
940 } catch (Exception e) {
941 throw new PAPException(e);
945 private XACMLPapServlet getPapInstance() {
946 return new XACMLPapServlet();
949 private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
951 mapper.writeValue(response.getOutputStream(), value);
952 } catch (Exception e) {
957 private void setResponseError(HttpServletResponse response, int responseCode, String message) {
959 if (message != null && !message.isEmpty()) {
960 response.sendError(responseCode, message);
962 } catch (IOException e) {
963 LOGGER.error("Error setting Error response Header ", e);