2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.pap.xacml.rest;
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.fasterxml.jackson.databind.ObjectMapper;
27 import java.io.IOException;
28 import java.io.UnsupportedEncodingException;
29 import java.net.URLDecoder;
30 import java.nio.file.Files;
31 import java.nio.file.Paths;
32 import java.util.Arrays;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Scanner;
38 import javax.servlet.ServletException;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
42 import org.onap.policy.common.logging.OnapLoggingContext;
43 import org.onap.policy.common.logging.eelf.MessageCodes;
44 import org.onap.policy.common.logging.eelf.PolicyLogger;
45 import org.onap.policy.common.logging.flexlogger.FlexLogger;
46 import org.onap.policy.common.logging.flexlogger.Logger;
47 import org.onap.policy.pap.xacml.rest.components.PolicyDbDao;
48 import org.onap.policy.pap.xacml.rest.components.PolicyDbDaoTransaction;
49 import org.onap.policy.pap.xacml.rest.handler.PushPolicyHandler;
50 import org.onap.policy.xacml.api.XACMLErrorConstants;
51 import org.onap.policy.xacml.api.pap.OnapPDP;
52 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
53 import org.onap.policy.xacml.api.pap.PAPPolicyEngine;
54 import org.onap.policy.xacml.std.pap.StdPDP;
55 import org.onap.policy.xacml.std.pap.StdPDPGroup;
56 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
58 public class ConsoleAndApiService {
60 private static final String SPACE_UNIMPLEMENTED = " UNIMPLEMENTED";
61 private static final String XACMLPAPSERVLET_DO_AC_PUT_COMMIT_TRANS = "XACMLPapServlet doACPut commitTransaction";
62 private static final String UNIMPLEMENTED = "UNIMPLEMENTED";
63 private static final String APPLICATION_JSON = "application/json";
64 private static final String CONTENT_TYPE = "content-type";
65 private static final String TO_GROUP = ",to group=";
66 private static final String PDP_ID = "pdpId";
67 private static final String XACML_PAP_SERVLET_DO_AC_PUT = "XACMLPapServlet.doACPut";
68 private static final String UNKNOWN_GROUP_ID = "Unknown groupId '";
69 private static final Logger LOGGER = FlexLogger.getLogger(ConsoleAndApiService.class);
70 private static final Logger auditLogger = FlexLogger.getLogger("auditLogger");
71 private static final String ADD_GROUP_ERROR = "addGroupError";
72 private static final String REGEX = "[0-9a-zA-Z._, ]*";
73 private static final String TRANSACTIONFAILED = "Transaction Failed - See Error.log";
74 private static final String PAPSERVLETDOACPOST = "XACMLPapServlet.doACPost";
75 private static final String ACPOSTCOMMITTRANS = "XACMLPapServlet doACPost commitTransaction";
76 private static final String XACMLPAPSERVLET = "XACMLPapServlet";
77 private static final String SUCCESS = "Success";
78 private static final String ERROR = "error";
79 private static final String MESSAGE = "message";
80 private static final String POLICYID = "policyId";
81 private static final String TRANSENDED = "Transaction Ended Successfully";
84 * Requests from the Admin Console for operations not on single specific objects.
86 * @param request Servlet request
87 * @param response Servlet response
88 * @param groupId the group id
89 * @param loggingContext the logging context
90 * @param papEngine the pap engine
91 * @throws ServletException the servlet exception
92 * @throws IOException Signals that an I/O exception has occurred.
94 public void doAcPost(HttpServletRequest request, HttpServletResponse response, String groupId,
95 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
96 PolicyDbDaoTransaction doAcPostTransaction = null;
98 String groupName = request.getParameter("groupName");
99 String groupDescription = request.getParameter("groupDescription");
100 String apiflag = request.getParameter("apiflag");
101 String userId = request.getParameter("userId");
102 if (groupName != null && groupDescription != null) {
103 // Args: group=<groupId> groupName=<name>
104 // groupDescription=<description> <= create a new group
105 loggingContext.setServiceName("AC:PAP.createGroup");
106 String unescapedName = null;
107 String unescapedDescription = null;
109 unescapedName = URLDecoder.decode(groupName, "UTF-8");
110 unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
111 } catch (UnsupportedEncodingException e) {
114 PolicyDbDaoTransaction newGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
116 newGroupTransaction.createGroup(PolicyDbDao.createNewPdpGroupId(unescapedName), unescapedName,
117 unescapedDescription, PAPSERVLETDOACPOST);
118 papEngine.newGroup(unescapedName, unescapedDescription);
119 loggingContext.metricStarted();
120 newGroupTransaction.commitTransaction();
121 loggingContext.metricEnded();
122 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
123 } catch (Exception e) {
124 newGroupTransaction.rollbackTransaction();
125 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
126 " Unable to create new group");
127 loggingContext.transactionEnded();
128 PolicyLogger.audit(TRANSACTIONFAILED);
129 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
130 "Unable to create new group '" + groupId + "'");
133 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
134 if (LOGGER.isDebugEnabled()) {
135 LOGGER.debug("New Group '" + groupId + "' created");
137 auditLogger.info(SUCCESS);
138 PolicyLogger.audit(TRANSENDED);
141 // for all remaining POST operations the group must exist before the
142 // operation can be done
143 OnapPDPGroup group = null;
145 group = papEngine.getGroup(groupId);
146 } catch (PAPException e) {
150 String message = UNKNOWN_GROUP_ID + groupId + "'";
151 // for fixing Header Manipulation of Fortify issue
152 if (!message.matches(REGEX)) {
153 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
154 response.addHeader(ERROR, ADD_GROUP_ERROR);
155 response.addHeader(MESSAGE, "GroupId Id is not valid");
158 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
159 loggingContext.transactionEnded();
160 PolicyLogger.audit(TRANSACTIONFAILED);
161 if (apiflag != null) {
162 response.addHeader(ERROR, "unknownGroupId");
163 response.addHeader("operation", "push");
164 response.addHeader(MESSAGE, message);
165 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
167 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
172 // If the request contains a policyId then we know we are pushing
174 if (request.getParameter(POLICYID) != null) {
175 String policyName = request.getParameter(POLICYID);
176 List<String> policyIdList = Arrays.asList(policyName.split(","));
178 loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
179 LOGGER.info("PushPolicy Request - " + policyName + ", UserId - " + userId);
181 StdPDPGroup updatedGroup = null;
182 StdPDPPolicy policyForSafetyCheck = new StdPDPPolicy();
183 for (String policyId : policyIdList) {
184 PolicyDbDaoTransaction addPolicyToGroupTransaction =
185 XACMLPapServlet.getPolicyDbDao().getNewTransaction();
187 // Copying the policy to the file system and updating groups
189 LOGGER.info("PapServlet: calling PolicyDBDao.addPolicyToGroup()");
190 updatedGroup = addPolicyToGroupTransaction.addPolicyToGroup(group.getId(), policyId,
191 PAPSERVLETDOACPOST, userId);
192 loggingContext.metricStarted();
193 addPolicyToGroupTransaction.commitTransaction();
194 loggingContext.metricEnded();
195 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
196 LOGGER.info("PapServlet: addPolicyToGroup() succeeded, transaction was committed");
198 if (policyId.contains("Config_MS_") || policyId.contains("BRMS_Param")) {
199 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
200 policyForSafetyCheck.setId(policyId);
201 if (pushPolicyHandler.preSafetyCheck(policyForSafetyCheck,
202 XACMLPapServlet.getConfigHome())) {
203 LOGGER.debug("Precheck Successful.");
207 // delete temporary policy file from the bin directory
208 Files.deleteIfExists(Paths.get(policyId));
210 } catch (Exception e) {
211 addPolicyToGroupTransaction.rollbackTransaction();
212 String message = "Policy '" + policyName + "' not copied to group '" + groupId + "': " + e;
213 // for fixing Header Manipulation of Fortify issue
214 if (!message.matches(REGEX)) {
215 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
216 response.addHeader(ERROR, ADD_GROUP_ERROR);
217 response.addHeader(MESSAGE, "Policy Id is not valid");
220 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
221 loggingContext.transactionEnded();
222 PolicyLogger.audit(TRANSACTIONFAILED);
223 if (apiflag != null) {
224 response.addHeader(ERROR, "policyCopyError");
225 response.addHeader(MESSAGE, message);
226 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
228 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
235 * If request comes from the API we need to run the PolicyDBDao updateGroup() to notify other paps of
236 * the change. The GUI does this from the POLICY-SDK-APP code.
239 // Get new transaction to perform updateGroup()
240 PolicyDbDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
242 // Assume that this is an update of an existing PDP
244 loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
246 acPutTransaction.updateGroup(updatedGroup, XACML_PAP_SERVLET_DO_AC_PUT, userId);
247 } catch (Exception e) {
248 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
249 " Error occurred when notifying PAPs of a group change: " + e);
250 throw new PAPException(e.getMessage());
253 LOGGER.info("Calling updatGroup() with new group");
254 papEngine.updateGroup(updatedGroup);
256 LOGGER.info("Group - '" + updatedGroup.getId() + "' updated");
258 // Commit transaction to send notification to other PAPs
259 loggingContext.metricStarted();
260 acPutTransaction.commitTransaction();
261 loggingContext.metricEnded();
262 PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
263 // Group changed to send notification to PDPs, which
264 // might include changing the policies
265 getPapInstance().groupChanged(updatedGroup, loggingContext);
266 loggingContext.transactionEnded();
267 LOGGER.info(SUCCESS);
268 } catch (Exception e) {
269 acPutTransaction.rollbackTransaction();
270 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " API PUT exception");
271 loggingContext.transactionEnded();
272 PolicyLogger.audit(TRANSACTIONFAILED);
273 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW
274 + "Exception occurred when updating the group from API.";
275 LOGGER.error(message);
276 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
277 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
278 response.addHeader(ERROR, ADD_GROUP_ERROR);
279 response.addHeader(MESSAGE, message);
282 // policy file copied ok and the Group was updated on the PDP
283 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
284 response.addHeader("operation", "push");
285 response.addHeader(POLICYID, policyName);
286 response.addHeader("groupId", groupId);
288 LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'");
289 loggingContext.transactionEnded();
290 auditLogger.info(SUCCESS);
291 LOGGER.info(TRANSENDED);
292 } else if (request.getParameter("default") != null) {
293 // Args: group=<groupId> default=true <= make default
294 // change the current default group to be the one identified in
296 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
297 // This is a POST operation rather than a PUT "update group"
298 // because of the side-effect that the current default group is
300 // It should never be the case that multiple groups are
301 // currently marked as the default, but protect against that
303 PolicyDbDaoTransaction setDefaultGroupTransaction =
304 XACMLPapServlet.getPolicyDbDao().getNewTransaction();
306 setDefaultGroupTransaction.changeDefaultGroup(group, PAPSERVLETDOACPOST);
307 papEngine.setDefaultGroup(group);
308 loggingContext.metricStarted();
309 setDefaultGroupTransaction.commitTransaction();
310 loggingContext.metricEnded();
311 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
312 } catch (Exception e) {
313 setDefaultGroupTransaction.rollbackTransaction();
314 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " Unable to set group");
315 loggingContext.transactionEnded();
316 PolicyLogger.audit(TRANSACTIONFAILED);
317 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
318 "Unable to set group '" + groupId + "' to default");
321 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
322 if (LOGGER.isDebugEnabled()) {
323 LOGGER.debug("Group- '" + groupId + "' set to be default");
325 auditLogger.info(SUCCESS);
326 LOGGER.info(TRANSENDED);
327 } else if (request.getParameter(PDP_ID) != null) {
328 doAcPostTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
329 // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
330 loggingContext.setServiceName("AC:PAP.movePDP");
331 String pdpId = request.getParameter(PDP_ID);
332 OnapPDP pdp = papEngine.getPDP(pdpId);
333 final OnapPDPGroup originalGroup = papEngine.getPDPGroup(pdp);
335 doAcPostTransaction.movePdp(pdp, group, PAPSERVLETDOACPOST);
336 } catch (Exception e) {
337 doAcPostTransaction.rollbackTransaction();
338 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
339 " Error while moving pdp in the database: " + "pdp=" + pdp.getId() + TO_GROUP
341 throw new PAPException(e.getMessage());
343 papEngine.movePDP(pdp, group);
344 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
345 if (LOGGER.isDebugEnabled()) {
347 "PDP - '" + pdp.getId() + "' moved to group - '" + group.getId() + "' set to be default");
349 // update the status of both the original group and the new one
350 ((StdPDPGroup) originalGroup).resetStatus();
351 ((StdPDPGroup) group).resetStatus();
352 // Need to notify the PDP that it's config may have changed
353 getPapInstance().pdpChanged(pdp, loggingContext);
354 loggingContext.metricStarted();
355 doAcPostTransaction.commitTransaction();
356 loggingContext.metricEnded();
357 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
358 loggingContext.transactionEnded();
359 auditLogger.info(SUCCESS);
360 PolicyLogger.audit(TRANSENDED);
362 } catch (PAPException e) {
363 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC POST exception");
364 loggingContext.transactionEnded();
365 PolicyLogger.audit(TRANSACTIONFAILED);
366 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
371 * Requests from the Admin Console to GET info about the Groups and PDPs.
373 * @param request the request
374 * @param response the response
375 * @param groupId the group id
376 * @param loggingContext the logging context
377 * @param papEngine the pap engine
378 * @throws IOException Signals that an I/O exception has occurred.
380 public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId,
381 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
383 String parameterDefault = request.getParameter("default");
384 String pdpId = request.getParameter(PDP_ID);
385 String pdpGroup = request.getParameter("getPDPGroup");
386 if ("".equals(groupId)) {
387 // request IS from AC but does not identify a group by name
388 if (parameterDefault != null) {
389 // Request is for the Default group (whatever its id)
390 loggingContext.setServiceName("AC:PAP.getDefaultGroup");
391 OnapPDPGroup group = papEngine.getDefaultGroup();
392 // convert response object to JSON and include in the
394 mapperWriteValue(new ObjectMapper(), response, group);
395 if (LOGGER.isDebugEnabled()) {
396 LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
398 response.setStatus(HttpServletResponse.SC_OK);
399 response.setHeader(CONTENT_TYPE, APPLICATION_JSON);
401 response.getOutputStream().close();
402 } catch (IOException e) {
405 loggingContext.transactionEnded();
406 auditLogger.info(SUCCESS);
407 PolicyLogger.audit(TRANSENDED);
409 } else if (pdpId != null) {
410 // Request is related to a PDP
411 if (pdpGroup == null) {
412 // Request is for the (unspecified) group containing a
414 loggingContext.setServiceName("AC:PAP.getPDP");
417 pdp = papEngine.getPDP(pdpId);
418 } catch (PAPException e) {
421 // convert response object to JSON and include in the
423 mapperWriteValue(new ObjectMapper(), response, pdp);
424 if (LOGGER.isDebugEnabled()) {
425 LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
427 response.setStatus(HttpServletResponse.SC_OK);
428 response.setHeader(CONTENT_TYPE, APPLICATION_JSON);
430 response.getOutputStream().close();
431 } catch (IOException e) {
434 loggingContext.transactionEnded();
435 auditLogger.info(SUCCESS);
436 PolicyLogger.audit(TRANSENDED);
439 // Request is for the group containing a given PDP
440 loggingContext.setServiceName("AC:PAP.getGroupForPDP");
441 OnapPDPGroup group = null;
443 OnapPDP pdp = papEngine.getPDP(pdpId);
444 group = papEngine.getPDPGroup(pdp);
445 } catch (PAPException e) {
448 // convert response object to JSON and include in the
450 mapperWriteValue(new ObjectMapper(), response, group);
451 if (LOGGER.isDebugEnabled()) {
452 LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
454 response.setStatus(HttpServletResponse.SC_OK);
455 response.setHeader(CONTENT_TYPE, APPLICATION_JSON);
457 response.getOutputStream().close();
458 } catch (IOException e) {
461 loggingContext.transactionEnded();
462 auditLogger.info(SUCCESS);
463 PolicyLogger.audit(TRANSENDED);
467 // request is for top-level properties about all groups
468 loggingContext.setServiceName("AC:PAP.getAllGroups");
469 Set<OnapPDPGroup> groups = null;
471 groups = papEngine.getOnapPDPGroups();
472 } catch (PAPException e) {
473 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
474 loggingContext.transactionEnded();
475 PolicyLogger.audit(TRANSACTIONFAILED);
476 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
479 // convert response object to JSON and include in the
481 mapperWriteValue(new ObjectMapper(), response, groups);
482 if (LOGGER.isDebugEnabled()) {
483 LOGGER.debug("GET All groups req");
485 response.setStatus(HttpServletResponse.SC_OK);
486 response.setHeader(CONTENT_TYPE, APPLICATION_JSON);
488 response.getOutputStream().close();
489 } catch (IOException e) {
492 loggingContext.transactionEnded();
493 auditLogger.info(SUCCESS);
494 PolicyLogger.audit(TRANSENDED);
498 // for all other GET operations the group must exist before the
499 // operation can be done
500 OnapPDPGroup group = null;
502 group = papEngine.getGroup(groupId);
503 } catch (PAPException e) {
507 String message = UNKNOWN_GROUP_ID + groupId + "'";
508 // for fixing Header Manipulation of Fortify issue
509 if (!message.matches(REGEX)) {
510 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
511 response.addHeader(ERROR, ADD_GROUP_ERROR);
512 response.addHeader(MESSAGE, "Group Id is not valid");
515 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
516 loggingContext.transactionEnded();
517 PolicyLogger.audit(TRANSACTIONFAILED);
518 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
521 // Figure out which request this is based on the parameters
522 String policyId = request.getParameter(POLICYID);
523 if (policyId != null) {
525 loggingContext.setServiceName("AC:PAP.getPolicy");
526 // convert response object to JSON and include in the response
527 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
528 loggingContext.transactionEnded();
529 PolicyLogger.audit(TRANSACTIONFAILED);
530 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
532 // No other parameters, so return the identified Group
533 loggingContext.setServiceName("AC:PAP.getGroup");
534 // convert response object to JSON and include in the response
535 mapperWriteValue(new ObjectMapper(), response, group);
536 if (LOGGER.isDebugEnabled()) {
537 LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
539 response.setStatus(HttpServletResponse.SC_OK);
540 response.setHeader(CONTENT_TYPE, APPLICATION_JSON);
542 response.getOutputStream().close();
543 } catch (IOException e) {
546 loggingContext.transactionEnded();
547 auditLogger.info(SUCCESS);
548 PolicyLogger.audit(TRANSENDED);
551 // Currently there are no other GET calls from the AC.
552 // The AC uses the "GET All Groups" operation to fill its local
553 // cache and uses that cache for all other GETs without calling the
555 // Other GETs that could be called:
556 // Specific Group (groupId=<groupId>)
557 // A Policy (groupId=<groupId> policyId=<policyId>)
558 // A PDP (groupId=<groupId> pdpId=<pdpId>)
559 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
560 loggingContext.transactionEnded();
561 PolicyLogger.audit(TRANSACTIONFAILED);
562 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, UNIMPLEMENTED);
563 } catch (PAPException e) {
564 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
565 loggingContext.transactionEnded();
566 PolicyLogger.audit(TRANSACTIONFAILED);
567 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
572 * Requests from the Admin Console to create new items or update existing ones.
574 * @param request the request
575 * @param response the response
576 * @param groupId the group id
577 * @param loggingContext the logging context
578 * @param papEngine the pap engine
579 * @throws IOException Signals that an I/O exception has occurred.
581 public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId,
582 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
583 PolicyDbDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
585 String userId = request.getParameter("userId");
586 // for PUT operations the group may or may not need to exist before
587 // the operation can be done
588 OnapPDPGroup group = papEngine.getGroup(groupId);
589 // determine the operation needed based on the parameters in the
591 // for remaining operations the group must exist before the
592 // operation can be done
594 String message = UNKNOWN_GROUP_ID + groupId + "'";
595 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
596 loggingContext.transactionEnded();
597 PolicyLogger.audit(TRANSACTIONFAILED);
598 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
599 acPutTransaction.rollbackTransaction();
602 if (request.getParameter("policy") != null) {
603 // group=<groupId> policy=<policyId> contents=policy file <=
604 // Create new policy file in group dir, or replace it if it
605 // already exists (do not touch properties)
606 loggingContext.setServiceName("AC:PAP.putPolicy");
607 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
608 + " PARTIALLY IMPLEMENTED!!! ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
609 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
610 loggingContext.transactionEnded();
611 PolicyLogger.audit(TRANSACTIONFAILED);
612 auditLogger.info(SUCCESS);
613 PolicyLogger.audit(TRANSENDED);
614 acPutTransaction.rollbackTransaction();
615 } else if (request.getParameter(PDP_ID) != null) {
616 // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP
617 // or Update an Existing one
618 String pdpId = request.getParameter(PDP_ID);
619 if (papEngine.getPDP(pdpId) == null) {
620 loggingContext.setServiceName("AC:PAP.createPDP");
622 loggingContext.setServiceName("AC:PAP.updatePDP");
624 // get the request content into a String
626 // read the inputStream into a buffer (trick found online scans
627 // entire input looking for end-of-file)
629 Scanner scanner = new Scanner(request.getInputStream());
630 scanner.useDelimiter("\\A");
631 json = scanner.hasNext() ? scanner.next() : "";
633 } catch (IOException e) {
636 LOGGER.info("JSON request from AC: " + json);
637 // convert Object sent as JSON into local object
638 ObjectMapper mapper = new ObjectMapper();
639 Object objectFromJson = null;
641 objectFromJson = mapper.readValue(json, StdPDP.class);
642 } catch (Exception e) {
645 if (pdpId == null || objectFromJson == null || !(objectFromJson instanceof StdPDP)
646 || ((StdPDP) objectFromJson).getId() == null
647 || !((StdPDP) objectFromJson).getId().equals(pdpId)) {
648 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId
649 + " objectFromJSON=" + objectFromJson);
650 loggingContext.transactionEnded();
651 PolicyLogger.audit(TRANSACTIONFAILED);
652 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
653 "Bad input pdpid for object:" + objectFromJson);
655 StdPDP pdp = (StdPDP) objectFromJson;
657 OnapPDP origPdp = null;
659 origPdp = papEngine.getPDP(pdpId);
660 } catch (PAPException e) {
663 if (origPdp == null) {
664 // this is a request to create a new PDP object
666 acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
667 pdp.getDescription(), pdp.getJmxPort(), XACML_PAP_SERVLET_DO_AC_PUT);
668 papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
669 } catch (Exception e) {
670 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
671 " Error while adding pdp to group in the database: " + "pdp=" + (pdp.getId())
672 + TO_GROUP + group.getId());
673 throw new PAPException(e.getMessage());
676 // this is a request to update the pdp
678 acPutTransaction.updatePdp(pdp, XACML_PAP_SERVLET_DO_AC_PUT);
679 papEngine.updatePDP(pdp);
680 } catch (Exception e) {
681 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
682 " Error while updating pdp in the database: " + "pdp=" + pdp.getId());
683 throw new PAPException(e.getMessage());
686 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
687 if (LOGGER.isDebugEnabled()) {
688 LOGGER.debug("PDP '" + pdpId + "' created/updated");
690 // adjust the group's state including the new PDP
691 ((StdPDPGroup) group).resetStatus();
692 // this might affect the PDP, so notify it of the change
693 getPapInstance().pdpChanged(pdp, loggingContext);
694 loggingContext.metricStarted();
695 acPutTransaction.commitTransaction();
696 loggingContext.metricEnded();
697 PolicyLogger.metrics(XACMLPAPSERVLET_DO_AC_PUT_COMMIT_TRANS);
698 loggingContext.transactionEnded();
699 auditLogger.info(SUCCESS);
700 PolicyLogger.audit(TRANSENDED);
703 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, XACMLPAPSERVLET,
704 " Error while adding pdp to group in the database: " + "pdp=null" + TO_GROUP
706 throw new PAPException("PDP is null");
707 } catch (Exception e) {
708 throw new PAPException("PDP is null" + e.getMessage() + e);
711 } else if (request.getParameter("pipId") != null) {
712 // group=<groupId> pipId=<pipEngineId> contents=pip properties
713 // <= add a PIP to pip config, or replace it if it already
714 // exists (lenient operation)
715 loggingContext.setServiceName("AC:PAP.putPIP");
716 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + UNIMPLEMENTED);
717 loggingContext.transactionEnded();
718 PolicyLogger.audit(TRANSACTIONFAILED);
719 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, UNIMPLEMENTED);
720 acPutTransaction.rollbackTransaction();
722 // Assume that this is an update of an existing PDP Group
723 // ARGS: group=<groupId> <= Update an Existing Group
724 loggingContext.setServiceName("AC:PAP.updateGroup");
725 // get the request content into a String
727 // read the inputStream into a buffer (trick found online scans
728 // entire input looking for end-of-file)
730 Scanner scanner = new Scanner(request.getInputStream());
731 scanner.useDelimiter("\\A");
732 json = scanner.hasNext() ? scanner.next() : "";
734 } catch (IOException e) {
737 LOGGER.info("JSON request from AC: " + json);
738 // convert Object sent as JSON into local object
739 ObjectMapper mapper = new ObjectMapper();
740 Object objectFromJson = null;
742 objectFromJson = mapper.readValue(json, StdPDPGroup.class);
743 } catch (Exception e) {
746 if (!(objectFromJson instanceof StdPDPGroup)
747 || !((StdPDPGroup) objectFromJson).getId().equals(group.getId())) {
748 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id="
749 + group.getId() + " objectFromJSON=" + objectFromJson);
750 loggingContext.transactionEnded();
751 PolicyLogger.audit(TRANSACTIONFAILED);
752 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
753 "Bad input id for object:" + objectFromJson);
755 // The Path on the PAP side is not carried on the RESTful
756 // interface with the AC
757 // (because it is local to the PAP)
758 // so we need to fill that in before submitting the group for
760 if (objectFromJson != null) {
761 ((StdPDPGroup) objectFromJson).setDirectory(((StdPDPGroup) group).getDirectory());
764 if ("delete".equals(((StdPDPGroup) objectFromJson).getOperation())) {
765 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doDelete", userId);
767 acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, XACML_PAP_SERVLET_DO_AC_PUT, userId);
769 } catch (Exception e) {
770 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
771 + "group=" + group.getId());
773 throw new PAPException(e.getMessage());
776 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
777 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJson;
778 if (pushPolicyHandler.preSafetyCheck(updatedGroup, XACMLPapServlet.getConfigHome())) {
779 LOGGER.debug("Precheck Successful.");
782 papEngine.updateGroup((StdPDPGroup) objectFromJson);
783 } catch (PAPException e) {
786 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
787 if (LOGGER.isDebugEnabled()) {
788 LOGGER.debug("Group '" + group.getId() + "' updated");
790 loggingContext.metricStarted();
791 acPutTransaction.commitTransaction();
792 loggingContext.metricEnded();
793 PolicyLogger.metrics(XACMLPAPSERVLET_DO_AC_PUT_COMMIT_TRANS);
794 // Group changed, which might include changing the policies
795 getPapInstance().groupChanged(group, loggingContext);
796 loggingContext.transactionEnded();
797 auditLogger.info(SUCCESS);
798 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());
811 * Requests from the Admin Console to delete/remove items.
813 * @param request the request
814 * @param response the response
815 * @param groupId the group id
816 * @param loggingContext the logging context
817 * @param papEngine the pap engine
818 * @throws IOException Signals that an I/O exception has occurred.
820 public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
821 OnapLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
822 PolicyDbDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
824 // for all DELETE operations the group must exist before the
825 // operation can be done
826 loggingContext.setServiceName("AC:PAP.delete");
827 OnapPDPGroup group = papEngine.getGroup(groupId);
829 String message = UNKNOWN_GROUP_ID + groupId + "'";
830 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
831 loggingContext.transactionEnded();
832 PolicyLogger.audit(TRANSACTIONFAILED);
833 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, UNKNOWN_GROUP_ID + groupId + "'");
834 removePdpOrGroupTransaction.rollbackTransaction();
837 // determine the operation needed based on the parameters in the
839 if (request.getParameter("policy") != null) {
840 // group=<groupId> policy=<policyId> [delete=<true|false>] <=
841 // delete policy file from group
842 loggingContext.setServiceName("AC:PAP.deletePolicy");
843 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + SPACE_UNIMPLEMENTED);
844 loggingContext.transactionEnded();
845 PolicyLogger.audit(TRANSACTIONFAILED);
846 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, UNIMPLEMENTED);
847 removePdpOrGroupTransaction.rollbackTransaction();
848 } else if (request.getParameter(PDP_ID) != null) {
849 // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
850 String pdpId = request.getParameter(PDP_ID);
851 OnapPDP pdp = papEngine.getPDP(pdpId);
852 removePdpFromGroup(removePdpOrGroupTransaction, pdp, papEngine);
853 // adjust the status of the group, which may have changed when
854 // we removed this PDP
855 ((StdPDPGroup) group).resetStatus();
856 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
857 // update the PDP and tell it that it has NO Policies (which
858 // prevents it from serving PEP Requests)
859 getPapInstance().pdpChanged(pdp, loggingContext);
860 loggingContext.metricStarted();
861 removePdpOrGroupTransaction.commitTransaction();
862 loggingContext.metricEnded();
863 PolicyLogger.metrics(XACMLPAPSERVLET_DO_AC_PUT_COMMIT_TRANS);
864 loggingContext.transactionEnded();
865 auditLogger.info(SUCCESS);
866 PolicyLogger.audit(TRANSENDED);
867 } else if (request.getParameter("pipId") != null) {
868 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for
870 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
871 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + SPACE_UNIMPLEMENTED);
872 loggingContext.transactionEnded();
873 PolicyLogger.audit(TRANSACTIONFAILED);
874 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, UNIMPLEMENTED);
875 removePdpOrGroupTransaction.rollbackTransaction();
877 // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>
878 // <= delete a group and move all its PDPs to the given group
879 String moveToGroupId = request.getParameter("movePDPsToGroupId");
880 OnapPDPGroup moveToGroup = null;
881 if (moveToGroupId != null) {
883 moveToGroup = papEngine.getGroup(moveToGroupId);
884 } catch (PAPException e) {
888 // get list of PDPs in the group being deleted so we can notify
889 // them that they got changed
890 Set<OnapPDP> movedPdps = new HashSet<>();
891 movedPdps.addAll(group.getOnapPdps());
892 // do the move/remove
893 deleteGroup(removePdpOrGroupTransaction, group, moveToGroup, papEngine);
894 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
895 // notify any PDPs in the removed set that their config may have
897 for (OnapPDP pdp : movedPdps) {
898 getPapInstance().pdpChanged(pdp, loggingContext);
900 loggingContext.metricStarted();
901 removePdpOrGroupTransaction.commitTransaction();
902 loggingContext.metricEnded();
903 PolicyLogger.metrics(XACMLPAPSERVLET_DO_AC_PUT_COMMIT_TRANS);
904 loggingContext.transactionEnded();
905 auditLogger.info(SUCCESS);
906 PolicyLogger.audit(TRANSENDED);
908 } catch (PAPException e) {
909 removePdpOrGroupTransaction.rollbackTransaction();
910 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC DELETE exception");
911 loggingContext.transactionEnded();
912 PolicyLogger.audit(TRANSACTIONFAILED);
913 setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
917 private void deleteGroup(PolicyDbDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group,
918 OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException {
920 removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete");
921 papEngine.removeGroup(group, moveToGroup);
922 } catch (Exception e) {
923 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, XACMLPAPSERVLET,
924 " Failed to delete PDP Group. Exception");
925 throw new PAPException(e.getMessage());
929 private void removePdpFromGroup(PolicyDbDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp,
930 PAPPolicyEngine papEngine) throws PAPException {
932 removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
933 papEngine.removePDP(pdp);
934 } catch (Exception e) {
935 throw new PAPException(e);
939 private XACMLPapServlet getPapInstance() {
940 return new XACMLPapServlet();
943 private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
945 mapper.writeValue(response.getOutputStream(), value);
946 } catch (Exception e) {
951 private void setResponseError(HttpServletResponse response, int responseCode, String message) {
953 if (message != null && !message.isEmpty()) {
954 response.sendError(responseCode, message);
956 } catch (IOException e) {
957 LOGGER.error("Error setting Error response Header ", e);