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;
25 import java.io.IOException;
26 import java.io.UnsupportedEncodingException;
27 import java.net.URLDecoder;
28 import java.nio.file.Files;
29 import java.nio.file.Paths;
30 import java.util.Arrays;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Scanner;
35 import javax.servlet.ServletException;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38 import org.onap.policy.common.logging.ONAPLoggingContext;
39 import org.onap.policy.common.logging.eelf.MessageCodes;
40 import org.onap.policy.common.logging.eelf.PolicyLogger;
41 import org.onap.policy.common.logging.flexlogger.FlexLogger;
42 import org.onap.policy.common.logging.flexlogger.Logger;
43 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao;
44 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
45 import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler;
46 import org.onap.policy.xacml.api.XACMLErrorConstants;
47 import org.onap.policy.xacml.api.pap.OnapPDP;
48 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
49 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
50 import org.onap.policy.xacml.std.pap.StdPDP;
51 import org.onap.policy.xacml.std.pap.StdPDPGroup;
52 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
54 public class ConsoleAndApiService {
56 private static final Logger LOGGER = FlexLogger.getLogger(ConsoleAndApiService.class);
57 private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
58 private static final String ADD_GROUP_ERROR = "addGroupError";
59 private static final String REGEX = "[0-9a-zA-Z._, ]*";
60 private static final String TRANSACTIONFAILED = "Transaction Failed - See Error.log";
61 private static final String PAPSERVLETDOACPOST = "XACMLPapServlet.doACPost";
62 private static final String ACPOSTCOMMITTRANS = "XACMLPapServlet doACPost commitTransaction";
63 private static final String XACMLPAPSERVLET = "XACMLPapServlet";
64 private static final String SUCCESS = "Success";
65 private static final String ERROR = "error";
66 private static final String MESSAGE = "message";
67 private static final String POLICYID = "policyId";
68 private static final String TRANSENDED = "Transaction Ended Successfully";
71 * Requests from the Admin Console for operations not on single specific objects.
73 * @param request Servlet request
74 * @param response Servlet response
75 * @param groupId the group id
76 * @param loggingContext the logging context
77 * @param papEngine the pap engine
78 * @throws ServletException the servlet exception
79 * @throws IOException Signals that an I/O exception has occurred.
81 public void doAcPost(HttpServletRequest request, HttpServletResponse response, String groupId,
82 ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
83 PolicyDBDaoTransaction doAcPostTransaction = null;
85 String groupName = request.getParameter("groupName");
86 String groupDescription = request.getParameter("groupDescription");
87 String apiflag = request.getParameter("apiflag");
88 String userId = request.getParameter("userId");
89 if (groupName != null && groupDescription != null) {
90 // Args: group=<groupId> groupName=<name>
91 // groupDescription=<description> <= create a new group
92 loggingContext.setServiceName("AC:PAP.createGroup");
93 String unescapedName = null;
94 String unescapedDescription = null;
96 unescapedName = URLDecoder.decode(groupName, "UTF-8");
97 unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
98 } catch (UnsupportedEncodingException e) {
101 PolicyDBDaoTransaction newGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
103 newGroupTransaction.createGroup(PolicyDBDao.createNewPDPGroupId(unescapedName), unescapedName,
104 unescapedDescription, PAPSERVLETDOACPOST);
105 papEngine.newGroup(unescapedName, unescapedDescription);
106 loggingContext.metricStarted();
107 newGroupTransaction.commitTransaction();
108 loggingContext.metricEnded();
109 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
110 } catch (Exception e) {
111 newGroupTransaction.rollbackTransaction();
112 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
113 " Unable to create new group");
114 loggingContext.transactionEnded();
115 PolicyLogger.audit(TRANSACTIONFAILED);
116 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
117 "Unable to create new group '" + groupId + "'");
120 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
121 if (LOGGER.isDebugEnabled()) {
122 LOGGER.debug("New Group '" + groupId + "' created");
124 auditLogger.info(SUCCESS);
125 PolicyLogger.audit(TRANSENDED);
128 // for all remaining POST operations the group must exist before the
129 // operation can be done
130 OnapPDPGroup group = null;
132 group = papEngine.getGroup(groupId);
133 } catch (PAPException e) {
137 String message = "Unknown groupId '" + groupId + "'";
138 // for fixing Header Manipulation of Fortify issue
139 if (!message.matches(REGEX)) {
140 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
141 response.addHeader(ERROR, ADD_GROUP_ERROR);
142 response.addHeader(MESSAGE, "GroupId Id is not valid");
145 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
146 loggingContext.transactionEnded();
147 PolicyLogger.audit(TRANSACTIONFAILED);
148 if (apiflag != null) {
149 response.addHeader(ERROR, "unknownGroupId");
150 response.addHeader("operation", "push");
151 response.addHeader(MESSAGE, message);
152 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
154 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
159 // If the request contains a policyId then we know we are pushing
161 if (request.getParameter(POLICYID) != null) {
162 String policyName = request.getParameter(POLICYID);
163 List<String> policyIdList = Arrays.asList(policyName.split(","));
165 loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
166 LOGGER.info("PushPolicy Request - " + policyName + ", UserId - " + userId);
168 StdPDPGroup updatedGroup = null;
169 StdPDPPolicy policyForSafetyCheck = new StdPDPPolicy();
170 for (String policyId : policyIdList) {
171 PolicyDBDaoTransaction addPolicyToGroupTransaction =
172 XACMLPapServlet.getPolicyDbDao().getNewTransaction();
174 // Copying the policy to the file system and updating groups
176 LOGGER.info("PapServlet: calling PolicyDBDao.addPolicyToGroup()");
177 updatedGroup = addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,
178 PAPSERVLETDOACPOST, userId);
179 loggingContext.metricStarted();
180 addPolicyToGroupTransaction.commitTransaction();
181 loggingContext.metricEnded();
182 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
183 LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed");
185 if (policyId.contains("Config_MS_") || policyId.contains("BRMS_Param")) {
186 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
187 policyForSafetyCheck.setId(policyId);
188 if (pushPolicyHandler.preSafetyCheck(policyForSafetyCheck, XACMLPapServlet.getConfigHome())) {
189 LOGGER.debug("Precheck Successful.");
193 // delete temporary policy file from the bin directory
194 Files.deleteIfExists(Paths.get(policyId));
196 } catch (Exception e) {
197 addPolicyToGroupTransaction.rollbackTransaction();
198 String message = "Policy '" + policyName + "' not copied to group '" + groupId + "': " + e;
199 // for fixing Header Manipulation of Fortify issue
200 if (!message.matches(REGEX)) {
201 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
202 response.addHeader(ERROR, ADD_GROUP_ERROR);
203 response.addHeader(MESSAGE, "Policy Id is not valid");
206 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
207 loggingContext.transactionEnded();
208 PolicyLogger.audit(TRANSACTIONFAILED);
209 if (apiflag != null) {
210 response.addHeader(ERROR, "policyCopyError");
211 response.addHeader(MESSAGE, message);
212 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
214 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
221 * If request comes from the API we need to run the PolicyDBDao updateGroup() to
222 * notify other paps of the change. The GUI does this from the POLICY-SDK-APP code.
225 // Get new transaction to perform updateGroup()
226 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
228 // Assume that this is an update of an existing PDP
230 loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
232 acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut", userId);
233 } catch (Exception e) {
234 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
235 " Error occurred when notifying PAPs of a group change: " + e);
236 throw new PAPException(e.getMessage());
239 LOGGER.info("Calling updatGroup() with new group");
240 papEngine.updateGroup(updatedGroup);
242 LOGGER.info("Group - '" + updatedGroup.getId() + "' updated");
244 // Commit transaction to send notification to other PAPs
245 loggingContext.metricStarted();
246 acPutTransaction.commitTransaction();
247 loggingContext.metricEnded();
248 PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
249 // Group changed to send notification to PDPs, which
250 // might include changing the policies
251 getPapInstance().groupChanged(updatedGroup, loggingContext);
252 loggingContext.transactionEnded();
253 LOGGER.info(SUCCESS);
254 } catch (Exception e) {
255 acPutTransaction.rollbackTransaction();
256 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " API PUT exception");
257 loggingContext.transactionEnded();
258 PolicyLogger.audit(TRANSACTIONFAILED);
259 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW
260 + "Exception occurred when updating the group from API.";
261 LOGGER.error(message);
262 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
263 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
264 response.addHeader(ERROR, ADD_GROUP_ERROR);
265 response.addHeader(MESSAGE, message);
268 // policy file copied ok and the Group was updated on the PDP
269 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
270 response.addHeader("operation", "push");
271 response.addHeader(POLICYID, policyName);
272 response.addHeader("groupId", groupId);
274 LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'");
275 loggingContext.transactionEnded();
276 auditLogger.info(SUCCESS);
277 LOGGER.info(TRANSENDED);
280 } else if (request.getParameter("default") != null) {
281 // Args: group=<groupId> default=true <= make default
282 // change the current default group to be the one identified in
284 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
285 // This is a POST operation rather than a PUT "update group"
286 // because of the side-effect that the current default group is
288 // It should never be the case that multiple groups are
289 // currently marked as the default, but protect against that
291 PolicyDBDaoTransaction setDefaultGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
293 setDefaultGroupTransaction.changeDefaultGroup(group, PAPSERVLETDOACPOST);
294 papEngine.setDefaultGroup(group);
295 loggingContext.metricStarted();
296 setDefaultGroupTransaction.commitTransaction();
297 loggingContext.metricEnded();
298 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
299 } catch (Exception e) {
300 setDefaultGroupTransaction.rollbackTransaction();
301 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " Unable to set group");
302 loggingContext.transactionEnded();
303 PolicyLogger.audit(TRANSACTIONFAILED);
304 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
305 "Unable to set group '" + groupId + "' to default");
308 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
309 if (LOGGER.isDebugEnabled()) {
310 LOGGER.debug("Group- '" + groupId + "' set to be default");
312 auditLogger.info(SUCCESS);
313 LOGGER.info(TRANSENDED);
315 } else if (request.getParameter("pdpId") != null) {
316 doAcPostTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
317 // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
318 loggingContext.setServiceName("AC:PAP.movePDP");
319 String pdpId = request.getParameter("pdpId");
320 OnapPDP pdp = papEngine.getPDP(pdpId);
321 OnapPDPGroup originalGroup = papEngine.getPDPGroup(pdp);
323 doAcPostTransaction.movePdp(pdp, group, PAPSERVLETDOACPOST);
324 } catch (Exception e) {
325 doAcPostTransaction.rollbackTransaction();
326 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
327 " Error while moving pdp in the database: " + "pdp=" + pdp.getId() + ",to group="
329 throw new PAPException(e.getMessage());
331 papEngine.movePDP(pdp, group);
332 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
333 if (LOGGER.isDebugEnabled()) {
335 "PDP - '" + pdp.getId() + "' moved to group - '" + group.getId() + "' set to be default");
337 // update the status of both the original group and the new one
338 ((StdPDPGroup) originalGroup).resetStatus();
339 ((StdPDPGroup) group).resetStatus();
340 // Need to notify the PDP that it's config may have changed
341 getPapInstance().pdpChanged(pdp, loggingContext);
342 loggingContext.metricStarted();
343 doAcPostTransaction.commitTransaction();
344 loggingContext.metricEnded();
345 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
346 loggingContext.transactionEnded();
347 auditLogger.info(SUCCESS);
348 PolicyLogger.audit(TRANSENDED);
351 } catch (PAPException e) {
352 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC POST exception");
353 loggingContext.transactionEnded();
354 PolicyLogger.audit(TRANSACTIONFAILED);
355 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
361 * Requests from the Admin Console to GET info about the Groups and PDPs.
363 * @param request the request
364 * @param response the response
365 * @param groupId the group id
366 * @param loggingContext the logging context
367 * @param papEngine the pap engine
368 * @throws IOException Signals that an I/O exception has occurred.
370 public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId,
371 ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
373 String parameterDefault = request.getParameter("default");
374 String pdpId = request.getParameter("pdpId");
375 String pdpGroup = request.getParameter("getPDPGroup");
376 if ("".equals(groupId)) {
377 // request IS from AC but does not identify a group by name
378 if (parameterDefault != null) {
379 // Request is for the Default group (whatever its id)
380 loggingContext.setServiceName("AC:PAP.getDefaultGroup");
381 OnapPDPGroup group = papEngine.getDefaultGroup();
382 // convert response object to JSON and include in the
384 mapperWriteValue(new ObjectMapper(), response, group);
385 if (LOGGER.isDebugEnabled()) {
386 LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
388 response.setStatus(HttpServletResponse.SC_OK);
389 response.setHeader("content-type", "application/json");
391 response.getOutputStream().close();
392 } catch (IOException e) {
395 loggingContext.transactionEnded();
396 auditLogger.info(SUCCESS);
397 PolicyLogger.audit(TRANSENDED);
399 } else if (pdpId != null) {
400 // Request is related to a PDP
401 if (pdpGroup == null) {
402 // Request is for the (unspecified) group containing a
404 loggingContext.setServiceName("AC:PAP.getPDP");
407 pdp = papEngine.getPDP(pdpId);
408 } catch (PAPException e) {
411 // convert response object to JSON and include in the
413 mapperWriteValue(new ObjectMapper(), response, pdp);
414 if (LOGGER.isDebugEnabled()) {
415 LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
417 response.setStatus(HttpServletResponse.SC_OK);
418 response.setHeader("content-type", "application/json");
420 response.getOutputStream().close();
421 } catch (IOException e) {
424 loggingContext.transactionEnded();
425 auditLogger.info(SUCCESS);
426 PolicyLogger.audit(TRANSENDED);
429 // Request is for the group containing a given PDP
430 loggingContext.setServiceName("AC:PAP.getGroupForPDP");
431 OnapPDPGroup group = null;
433 OnapPDP pdp = papEngine.getPDP(pdpId);
434 group = papEngine.getPDPGroup(pdp);
435 } catch (PAPException e) {
438 // convert response object to JSON and include in the
440 mapperWriteValue(new ObjectMapper(), response, group);
441 if (LOGGER.isDebugEnabled()) {
442 LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
444 response.setStatus(HttpServletResponse.SC_OK);
445 response.setHeader("content-type", "application/json");
447 response.getOutputStream().close();
448 } catch (IOException e) {
451 loggingContext.transactionEnded();
452 auditLogger.info(SUCCESS);
453 PolicyLogger.audit(TRANSENDED);
457 // request is for top-level properties about all groups
458 loggingContext.setServiceName("AC:PAP.getAllGroups");
459 Set<OnapPDPGroup> groups = null;
461 groups = papEngine.getOnapPDPGroups();
462 } catch (PAPException e) {
463 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
464 loggingContext.transactionEnded();
465 PolicyLogger.audit(TRANSACTIONFAILED);
466 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
469 // convert response object to JSON and include in the
471 mapperWriteValue(new ObjectMapper(), response, groups);
472 if (LOGGER.isDebugEnabled()) {
473 LOGGER.debug("GET All groups req");
475 response.setStatus(HttpServletResponse.SC_OK);
476 response.setHeader("content-type", "application/json");
478 response.getOutputStream().close();
479 } catch (IOException e) {
482 loggingContext.transactionEnded();
483 auditLogger.info(SUCCESS);
484 PolicyLogger.audit(TRANSENDED);
488 // for all other GET operations the group must exist before the
489 // operation can be done
490 OnapPDPGroup group = null;
492 group = papEngine.getGroup(groupId);
493 } catch (PAPException e) {
497 String message = "Unknown groupId '" + groupId + "'";
498 // for fixing Header Manipulation of Fortify issue
499 if (!message.matches(REGEX)) {
500 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
501 response.addHeader(ERROR, ADD_GROUP_ERROR);
502 response.addHeader(MESSAGE, "Group Id is not valid");
505 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
506 loggingContext.transactionEnded();
507 PolicyLogger.audit(TRANSACTIONFAILED);
508 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
511 // Figure out which request this is based on the parameters
512 String policyId = request.getParameter(POLICYID);
513 if (policyId != null) {
515 loggingContext.setServiceName("AC:PAP.getPolicy");
516 // convert response object to JSON and include in the response
517 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
518 loggingContext.transactionEnded();
519 PolicyLogger.audit(TRANSACTIONFAILED);
520 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
522 // No other parameters, so return the identified Group
523 loggingContext.setServiceName("AC:PAP.getGroup");
524 // convert response object to JSON and include in the response
525 mapperWriteValue(new ObjectMapper(), response, group);
526 if (LOGGER.isDebugEnabled()) {
527 LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
529 response.setStatus(HttpServletResponse.SC_OK);
530 response.setHeader("content-type", "application/json");
532 response.getOutputStream().close();
533 } catch (IOException e) {
536 loggingContext.transactionEnded();
537 auditLogger.info(SUCCESS);
538 PolicyLogger.audit(TRANSENDED);
541 // Currently there are no other GET calls from the AC.
542 // The AC uses the "GET All Groups" operation to fill its local
543 // cache and uses that cache for all other GETs without calling the
545 // Other GETs that could be called:
546 // Specific Group (groupId=<groupId>)
547 // A Policy (groupId=<groupId> policyId=<policyId>)
548 // A PDP (groupId=<groupId> pdpId=<pdpId>)
549 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
550 loggingContext.transactionEnded();
551 PolicyLogger.audit(TRANSACTIONFAILED);
552 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
553 } catch (PAPException e) {
554 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
555 loggingContext.transactionEnded();
556 PolicyLogger.audit(TRANSACTIONFAILED);
557 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
563 * Requests from the Admin Console to create new items or update existing ones.
565 * @param request the request
566 * @param response the response
567 * @param groupId the group id
568 * @param loggingContext the logging context
569 * @param papEngine the pap engine
570 * @throws IOException Signals that an I/O exception has occurred.
572 public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId,
573 ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
574 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
576 String userId = request.getParameter("userId");
577 // for PUT operations the group may or may not need to exist before
578 // the operation can be done
579 OnapPDPGroup group = papEngine.getGroup(groupId);
580 // determine the operation needed based on the parameters in the
582 // for remaining operations the group must exist before the
583 // operation can be done
585 String message = "Unknown groupId '" + groupId + "'";
586 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
587 loggingContext.transactionEnded();
588 PolicyLogger.audit(TRANSACTIONFAILED);
589 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
592 if (request.getParameter("policy") != null) {
593 // group=<groupId> policy=<policyId> contents=policy file <=
594 // Create new policy file in group dir, or replace it if it
595 // already exists (do not touch properties)
596 loggingContext.setServiceName("AC:PAP.putPolicy");
597 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
598 + " PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
599 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
600 loggingContext.transactionEnded();
601 PolicyLogger.audit(TRANSACTIONFAILED);
602 auditLogger.info(SUCCESS);
603 PolicyLogger.audit(TRANSENDED);
605 } else if (request.getParameter("pdpId") != null) {
606 // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP
607 // or Update an Existing one
608 String pdpId = request.getParameter("pdpId");
609 if (papEngine.getPDP(pdpId) == null) {
610 loggingContext.setServiceName("AC:PAP.createPDP");
612 loggingContext.setServiceName("AC:PAP.updatePDP");
614 // get the request content into a String
616 // read the inputStream into a buffer (trick found online scans
617 // entire input looking for end-of-file)
619 Scanner scanner = new Scanner(request.getInputStream());
620 scanner.useDelimiter("\\A");
621 json = scanner.hasNext() ? scanner.next() : "";
623 } catch (IOException e) {
626 LOGGER.info("JSON request from AC: " + json);
627 // convert Object sent as JSON into local object
628 ObjectMapper mapper = new ObjectMapper();
629 Object objectFromJson = null;
631 objectFromJson = mapper.readValue(json, StdPDP.class);
632 } catch (Exception e) {
635 if (pdpId == null || objectFromJson == null || !(objectFromJson instanceof StdPDP)
636 || ((StdPDP) objectFromJson).getId() == null
637 || !((StdPDP) objectFromJson).getId().equals(pdpId)) {
638 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId
639 + " objectFromJSON=" + objectFromJson);
640 loggingContext.transactionEnded();
641 PolicyLogger.audit(TRANSACTIONFAILED);
642 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
643 "Bad input pdpid for object:" + objectFromJson);
645 StdPDP pdp = (StdPDP) objectFromJson;
647 OnapPDP origPdp = null;
649 origPdp = papEngine.getPDP(pdpId);
650 } catch (PAPException e) {
653 if (origPdp == null) {
654 // this is a request to create a new PDP object
656 acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
657 pdp.getDescription(), pdp.getJmxPort(), "XACMLPapServlet.doACPut");
658 papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
659 } catch (Exception e) {
660 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
661 " Error while adding pdp to group in the database: " + "pdp=" + (pdp.getId())
662 + ",to group=" + group.getId());
663 throw new PAPException(e.getMessage());
666 // this is a request to update the pdp
668 acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
669 papEngine.updatePDP(pdp);
670 } catch (Exception e) {
671 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
672 " Error while updating pdp in the database: " + "pdp=" + pdp.getId());
673 throw new PAPException(e.getMessage());
676 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
677 if (LOGGER.isDebugEnabled()) {
678 LOGGER.debug("PDP '" + pdpId + "' created/updated");
680 // adjust the group's state including the new PDP
681 ((StdPDPGroup) group).resetStatus();
682 // this might affect the PDP, so notify it of the change
683 getPapInstance().pdpChanged(pdp, loggingContext);
684 loggingContext.metricStarted();
685 acPutTransaction.commitTransaction();
686 loggingContext.metricEnded();
687 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
688 loggingContext.transactionEnded();
689 auditLogger.info(SUCCESS);
690 PolicyLogger.audit(TRANSENDED);
694 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, XACMLPAPSERVLET,
695 " Error while adding pdp to group in the database: " + "pdp=null" + ",to group="
697 throw new PAPException("PDP is null");
698 } catch (Exception e) {
699 throw new PAPException("PDP is null" + e.getMessage() + e);
702 } else if (request.getParameter("pipId") != null) {
703 // group=<groupId> pipId=<pipEngineId> contents=pip properties
704 // <= add a PIP to pip config, or replace it if it already
705 // exists (lenient operation)
706 loggingContext.setServiceName("AC:PAP.putPIP");
707 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
708 loggingContext.transactionEnded();
709 PolicyLogger.audit(TRANSACTIONFAILED);
710 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
713 // Assume that this is an update of an existing PDP Group
714 // ARGS: group=<groupId> <= Update an Existing Group
715 loggingContext.setServiceName("AC:PAP.updateGroup");
716 // get the request content into a String
718 // read the inputStream into a buffer (trick found online scans
719 // entire input looking for end-of-file)
721 Scanner scanner = new Scanner(request.getInputStream());
722 scanner.useDelimiter("\\A");
723 json = scanner.hasNext() ? scanner.next() : "";
725 } catch (IOException e) {
728 LOGGER.info("JSON request from AC: " + json);
729 // convert Object sent as JSON into local object
730 ObjectMapper mapper = new ObjectMapper();
731 Object objectFromJson = null;
733 objectFromJson = mapper.readValue(json, StdPDPGroup.class);
734 } catch (Exception e) {
737 if (objectFromJson == null || !(objectFromJson instanceof StdPDPGroup)
738 || !((StdPDPGroup) objectFromJson).getId().equals(group.getId())) {
739 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id="
740 + group.getId() + " objectFromJSON=" + objectFromJson);
741 loggingContext.transactionEnded();
742 PolicyLogger.audit(TRANSACTIONFAILED);
743 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
744 "Bad input id for object:" + objectFromJson);
746 // The Path on the PAP side is not carried on the RESTful
747 // interface with the AC
748 // (because it is local to the PAP)
749 // so we need to fill that in before submitting the group for
751 if (objectFromJson != null) {
752 ((StdPDPGroup) objectFromJson).setDirectory(((StdPDPGroup) group).getDirectory());
755 if ("delete".equals(((StdPDPGroup) objectFromJson).getOperation())) {
756 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doDelete", userId);
758 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doACPut", userId);
760 } catch (Exception e) {
761 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
762 + "group=" + group.getId());
764 throw new PAPException(e.getMessage());
767 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
768 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJson;
769 if (pushPolicyHandler.preSafetyCheck(updatedGroup, XACMLPapServlet.getConfigHome())) {
770 LOGGER.debug("Precheck Successful.");
773 papEngine.updateGroup((StdPDPGroup) objectFromJson);
774 } catch (PAPException e) {
777 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
778 if (LOGGER.isDebugEnabled()) {
779 LOGGER.debug("Group '" + group.getId() + "' updated");
781 loggingContext.metricStarted();
782 acPutTransaction.commitTransaction();
783 loggingContext.metricEnded();
784 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
785 // Group changed, which might include changing the policies
786 getPapInstance().groupChanged(group, loggingContext);
787 loggingContext.transactionEnded();
788 auditLogger.info(SUCCESS);
789 PolicyLogger.audit(TRANSENDED);
792 } catch (PAPException e) {
794 acPutTransaction.rollbackTransaction();
795 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC PUT exception");
796 loggingContext.transactionEnded();
797 PolicyLogger.audit(TRANSACTIONFAILED);
798 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
804 * Requests from the Admin Console to delete/remove items.
806 * @param request the request
807 * @param response the response
808 * @param groupId the group id
809 * @param loggingContext the logging context
810 * @param papEngine the pap engine
811 * @throws IOException Signals that an I/O exception has occurred.
813 public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
814 ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
815 PolicyDBDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
817 // for all DELETE operations the group must exist before the
818 // operation can be done
819 loggingContext.setServiceName("AC:PAP.delete");
820 OnapPDPGroup group = papEngine.getGroup(groupId);
822 String message = "Unknown groupId '" + groupId + "'";
823 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
824 loggingContext.transactionEnded();
825 PolicyLogger.audit(TRANSACTIONFAILED);
826 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId + "'");
829 // determine the operation needed based on the parameters in the
831 if (request.getParameter("policy") != null) {
832 // group=<groupId> policy=<policyId> [delete=<true|false>] <=
833 // delete policy file from group
834 loggingContext.setServiceName("AC:PAP.deletePolicy");
835 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
836 loggingContext.transactionEnded();
837 PolicyLogger.audit(TRANSACTIONFAILED);
838 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
840 } else if (request.getParameter("pdpId") != null) {
841 // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
842 String pdpId = request.getParameter("pdpId");
843 OnapPDP pdp = papEngine.getPDP(pdpId);
844 removePdpFromGroup(removePdpOrGroupTransaction, pdp, papEngine);
845 // adjust the status of the group, which may have changed when
846 // we removed this PDP
847 ((StdPDPGroup) group).resetStatus();
848 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
849 // update the PDP and tell it that it has NO Policies (which
850 // prevents it from serving PEP Requests)
851 getPapInstance().pdpChanged(pdp, loggingContext);
852 loggingContext.metricStarted();
853 removePdpOrGroupTransaction.commitTransaction();
854 loggingContext.metricEnded();
855 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
856 loggingContext.transactionEnded();
857 auditLogger.info(SUCCESS);
858 PolicyLogger.audit(TRANSENDED);
860 } else if (request.getParameter("pipId") != null) {
861 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for
863 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
864 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
865 loggingContext.transactionEnded();
866 PolicyLogger.audit(TRANSACTIONFAILED);
867 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
870 // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>
871 // <= delete a group and move all its PDPs to the given group
872 String moveToGroupId = request.getParameter("movePDPsToGroupId");
873 OnapPDPGroup moveToGroup = null;
874 if (moveToGroupId != null) {
876 moveToGroup = papEngine.getGroup(moveToGroupId);
877 } catch (PAPException e) {
881 // get list of PDPs in the group being deleted so we can notify
882 // them that they got changed
883 Set<OnapPDP> movedPdps = new HashSet<>();
884 movedPdps.addAll(group.getOnapPdps());
885 // do the move/remove
886 deleteGroup(removePdpOrGroupTransaction, group, moveToGroup, papEngine);
887 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
888 // notify any PDPs in the removed set that their config may have
890 for (OnapPDP pdp : movedPdps) {
891 getPapInstance().pdpChanged(pdp, loggingContext);
893 loggingContext.metricStarted();
894 removePdpOrGroupTransaction.commitTransaction();
895 loggingContext.metricEnded();
896 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
897 loggingContext.transactionEnded();
898 auditLogger.info(SUCCESS);
899 PolicyLogger.audit(TRANSENDED);
902 } catch (PAPException e) {
903 removePdpOrGroupTransaction.rollbackTransaction();
904 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC DELETE exception");
905 loggingContext.transactionEnded();
906 PolicyLogger.audit(TRANSACTIONFAILED);
907 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
912 private void deleteGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group,
913 OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException {
915 removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete");
916 papEngine.removeGroup(group, moveToGroup);
917 } catch (Exception e) {
918 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, XACMLPAPSERVLET,
919 " Failed to delete PDP Group. Exception");
920 throw new PAPException(e.getMessage());
924 private void removePdpFromGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp,
925 PAPPolicyEngine papEngine) throws PAPException {
927 removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
928 papEngine.removePDP(pdp);
929 } catch (Exception e) {
930 throw new PAPException(e);
934 private XACMLPapServlet getPapInstance() {
935 return new XACMLPapServlet();
938 private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
940 mapper.writeValue(response.getOutputStream(), value);
941 } catch (Exception e) {
946 private void setResponseError(HttpServletResponse response, int responseCode, String message) {
948 if (message != null && !message.isEmpty()) {
949 response.sendError(responseCode, message);
951 } catch (IOException e) {
952 LOGGER.error("Error setting Error response Header ", e);