Merge "FIx Sonar Issues reported on ActionPolicyController"
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / ConsoleAndApiService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.policy.pap.xacml.rest;
22
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;
34 import java.util.Set;
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;
53
54 public class ConsoleAndApiService {
55
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";
69
70     /**
71      * Requests from the Admin Console for operations not on single specific objects.
72      *
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.
80      */
81     public void doAcPost(HttpServletRequest request, HttpServletResponse response, String groupId,
82             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
83         PolicyDBDaoTransaction doAcPostTransaction = null;
84         try {
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;
95                 try {
96                     unescapedName = URLDecoder.decode(groupName, "UTF-8");
97                     unescapedDescription = URLDecoder.decode(groupDescription, "UTF-8");
98                 } catch (UnsupportedEncodingException e) {
99                     LOGGER.error(e);
100                 }
101                 PolicyDBDaoTransaction newGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
102                 try {
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 + "'");
118                     return;
119                 }
120                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
121                 if (LOGGER.isDebugEnabled()) {
122                     LOGGER.debug("New Group '" + groupId + "' created");
123                 }
124                 auditLogger.info(SUCCESS);
125                 PolicyLogger.audit(TRANSENDED);
126                 return;
127             }
128             // for all remaining POST operations the group must exist before the
129             // operation can be done
130             OnapPDPGroup group = null;
131             try {
132                 group = papEngine.getGroup(groupId);
133             } catch (PAPException e) {
134                 LOGGER.error(e);
135             }
136             if (group == null) {
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");
143                     return;
144                 }
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);
153                 } else {
154                     setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
155                 }
156                 return;
157             }
158
159             // If the request contains a policyId then we know we are pushing
160             // the policy to PDP
161             if (request.getParameter(POLICYID) != null) {
162                 String policyName = request.getParameter(POLICYID);
163                 List<String> policyIdList = Arrays.asList(policyName.split(","));
164
165                 loggingContext.setServiceName("PolicyEngineAPI:PAP.postPolicy");
166                 LOGGER.info("PushPolicy Request - " + policyName + ", UserId - " + userId);
167
168                 StdPDPGroup updatedGroup = null;
169                 StdPDPPolicy policyForSafetyCheck = new StdPDPPolicy();
170                 for (String policyId : policyIdList) {
171                     PolicyDBDaoTransaction addPolicyToGroupTransaction =
172                             XACMLPapServlet.getPolicyDbDao().getNewTransaction();
173                     try {
174                         // Copying the policy to the file system and updating groups
175                         // in database
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");
184
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.");
190                             }
191                         }
192
193                         // delete temporary policy file from the bin directory
194                         Files.deleteIfExists(Paths.get(policyId));
195
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");
204                             return;
205                         }
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);
213                         } else {
214                             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
215                         }
216                         return;
217                     }
218                 }
219
220                 /*
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.
223                  */
224
225                 // Get new transaction to perform updateGroup()
226                 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
227                 try {
228                     // Assume that this is an update of an existing PDP
229                     // Group
230                     loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
231                     try {
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());
237                     }
238
239                     LOGGER.info("Calling updatGroup() with new group");
240                     papEngine.updateGroup(updatedGroup);
241
242                     LOGGER.info("Group - '" + updatedGroup.getId() + "' updated");
243
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);
266                     return;
267                 }
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);
273
274                 LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'");
275                 loggingContext.transactionEnded();
276                 auditLogger.info(SUCCESS);
277                 LOGGER.info(TRANSENDED);
278
279                 return;
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
283                 // the request.
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
287                 // also changed.
288                 // It should never be the case that multiple groups are
289                 // currently marked as the default, but protect against that
290                 // anyway.
291                 PolicyDBDaoTransaction setDefaultGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
292                 try {
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");
306                     return;
307                 }
308                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
309                 if (LOGGER.isDebugEnabled()) {
310                     LOGGER.debug("Group- '" + groupId + "' set to be default");
311                 }
312                 auditLogger.info(SUCCESS);
313                 LOGGER.info(TRANSENDED);
314                 return;
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);
322                 try {
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="
328                                     + group.getId());
329                     throw new PAPException(e.getMessage());
330                 }
331                 papEngine.movePDP(pdp, group);
332                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
333                 if (LOGGER.isDebugEnabled()) {
334                     LOGGER.debug(
335                             "PDP - '" + pdp.getId() + "' moved to group - '" + group.getId() + "' set to be default");
336                 }
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);
349                 return;
350             }
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());
356             return;
357         }
358     }
359
360     /**
361      * Requests from the Admin Console to GET info about the Groups and PDPs.
362      *
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.
369      */
370     public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId,
371             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
372         try {
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
383                     // response
384                     mapperWriteValue(new ObjectMapper(), response, group);
385                     if (LOGGER.isDebugEnabled()) {
386                         LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
387                     }
388                     response.setStatus(HttpServletResponse.SC_OK);
389                     response.setHeader("content-type", "application/json");
390                     try {
391                         response.getOutputStream().close();
392                     } catch (IOException e) {
393                         LOGGER.error(e);
394                     }
395                     loggingContext.transactionEnded();
396                     auditLogger.info(SUCCESS);
397                     PolicyLogger.audit(TRANSENDED);
398                     return;
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
403                         // given PDP
404                         loggingContext.setServiceName("AC:PAP.getPDP");
405                         OnapPDP pdp = null;
406                         try {
407                             pdp = papEngine.getPDP(pdpId);
408                         } catch (PAPException e) {
409                             LOGGER.error(e);
410                         }
411                         // convert response object to JSON and include in the
412                         // response
413                         mapperWriteValue(new ObjectMapper(), response, pdp);
414                         if (LOGGER.isDebugEnabled()) {
415                             LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
416                         }
417                         response.setStatus(HttpServletResponse.SC_OK);
418                         response.setHeader("content-type", "application/json");
419                         try {
420                             response.getOutputStream().close();
421                         } catch (IOException e) {
422                             LOGGER.error(e);
423                         }
424                         loggingContext.transactionEnded();
425                         auditLogger.info(SUCCESS);
426                         PolicyLogger.audit(TRANSENDED);
427                         return;
428                     } else {
429                         // Request is for the group containing a given PDP
430                         loggingContext.setServiceName("AC:PAP.getGroupForPDP");
431                         OnapPDPGroup group = null;
432                         try {
433                             OnapPDP pdp = papEngine.getPDP(pdpId);
434                             group = papEngine.getPDPGroup(pdp);
435                         } catch (PAPException e) {
436                             LOGGER.error(e);
437                         }
438                         // convert response object to JSON and include in the
439                         // response
440                         mapperWriteValue(new ObjectMapper(), response, group);
441                         if (LOGGER.isDebugEnabled()) {
442                             LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
443                         }
444                         response.setStatus(HttpServletResponse.SC_OK);
445                         response.setHeader("content-type", "application/json");
446                         try {
447                             response.getOutputStream().close();
448                         } catch (IOException e) {
449                             LOGGER.error(e);
450                         }
451                         loggingContext.transactionEnded();
452                         auditLogger.info(SUCCESS);
453                         PolicyLogger.audit(TRANSENDED);
454                         return;
455                     }
456                 } else {
457                     // request is for top-level properties about all groups
458                     loggingContext.setServiceName("AC:PAP.getAllGroups");
459                     Set<OnapPDPGroup> groups = null;
460                     try {
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());
467                         return;
468                     }
469                     // convert response object to JSON and include in the
470                     // response
471                     mapperWriteValue(new ObjectMapper(), response, groups);
472                     if (LOGGER.isDebugEnabled()) {
473                         LOGGER.debug("GET All groups req");
474                     }
475                     response.setStatus(HttpServletResponse.SC_OK);
476                     response.setHeader("content-type", "application/json");
477                     try {
478                         response.getOutputStream().close();
479                     } catch (IOException e) {
480                         LOGGER.error(e);
481                     }
482                     loggingContext.transactionEnded();
483                     auditLogger.info(SUCCESS);
484                     PolicyLogger.audit(TRANSENDED);
485                     return;
486                 }
487             }
488             // for all other GET operations the group must exist before the
489             // operation can be done
490             OnapPDPGroup group = null;
491             try {
492                 group = papEngine.getGroup(groupId);
493             } catch (PAPException e) {
494                 LOGGER.error(e);
495             }
496             if (group == null) {
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");
503                     return;
504                 }
505                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
506                 loggingContext.transactionEnded();
507                 PolicyLogger.audit(TRANSACTIONFAILED);
508                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
509                 return;
510             }
511             // Figure out which request this is based on the parameters
512             String policyId = request.getParameter(POLICYID);
513             if (policyId != null) {
514                 // retrieve a policy
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");
521             } else {
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() + "'");
528                 }
529                 response.setStatus(HttpServletResponse.SC_OK);
530                 response.setHeader("content-type", "application/json");
531                 try {
532                     response.getOutputStream().close();
533                 } catch (IOException e) {
534                     LOGGER.error(e);
535                 }
536                 loggingContext.transactionEnded();
537                 auditLogger.info(SUCCESS);
538                 PolicyLogger.audit(TRANSENDED);
539                 return;
540             }
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
544             // PAP.
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());
558             return;
559         }
560     }
561
562     /**
563      * Requests from the Admin Console to create new items or update existing ones.
564      *
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.
571      */
572     public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId,
573             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
574         PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
575         try {
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
581             // request
582             // for remaining operations the group must exist before the
583             // operation can be done
584             if (group == null) {
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);
590                 return;
591             }
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);
604                 return;
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");
611                 } else {
612                     loggingContext.setServiceName("AC:PAP.updatePDP");
613                 }
614                 // get the request content into a String
615                 String json = null;
616                 // read the inputStream into a buffer (trick found online scans
617                 // entire input looking for end-of-file)
618                 try {
619                     Scanner scanner = new Scanner(request.getInputStream());
620                     scanner.useDelimiter("\\A");
621                     json = scanner.hasNext() ? scanner.next() : "";
622                     scanner.close();
623                 } catch (IOException e) {
624                     LOGGER.error(e);
625                 }
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;
630                 try {
631                     objectFromJson = mapper.readValue(json, StdPDP.class);
632                 } catch (Exception e) {
633                     LOGGER.error(e);
634                 }
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);
644                 }
645                 StdPDP pdp = (StdPDP) objectFromJson;
646                 if (pdp != null) {
647                     OnapPDP origPdp = null;
648                     try {
649                         origPdp = papEngine.getPDP(pdpId);
650                     } catch (PAPException e) {
651                         LOGGER.error(e);
652                     }
653                     if (origPdp == null) {
654                         // this is a request to create a new PDP object
655                         try {
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());
664                         }
665                     } else {
666                         // this is a request to update the pdp
667                         try {
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());
674                         }
675                     }
676                     response.setStatus(HttpServletResponse.SC_NO_CONTENT);
677                     if (LOGGER.isDebugEnabled()) {
678                         LOGGER.debug("PDP '" + pdpId + "' created/updated");
679                     }
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);
691                     return;
692                 } else {
693                     try {
694                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, XACMLPAPSERVLET,
695                                 " Error while adding pdp to group in the database: " + "pdp=null" + ",to group="
696                                         + group.getId());
697                         throw new PAPException("PDP is null");
698                     } catch (Exception e) {
699                         throw new PAPException("PDP is null" + e.getMessage() + e);
700                     }
701                 }
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");
711                 return;
712             } else {
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
717                 String json = null;
718                 // read the inputStream into a buffer (trick found online scans
719                 // entire input looking for end-of-file)
720                 try {
721                     Scanner scanner = new Scanner(request.getInputStream());
722                     scanner.useDelimiter("\\A");
723                     json = scanner.hasNext() ? scanner.next() : "";
724                     scanner.close();
725                 } catch (IOException e) {
726                     LOGGER.error(e);
727                 }
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;
732                 try {
733                     objectFromJson = mapper.readValue(json, StdPDPGroup.class);
734                 } catch (Exception e) {
735                     LOGGER.error(e);
736                 }
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);
745                 }
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
750                 // update
751                 if (objectFromJson != null) {
752                     ((StdPDPGroup) objectFromJson).setDirectory(((StdPDPGroup) group).getDirectory());
753                 }
754                 try {
755                     if ("delete".equals(((StdPDPGroup) objectFromJson).getOperation())) {
756                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doDelete", userId);
757                     } else {
758                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doACPut", userId);
759                     }
760                 } catch (Exception e) {
761                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
762                             + "group=" + group.getId());
763                     LOGGER.error(e);
764                     throw new PAPException(e.getMessage());
765                 }
766
767                 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
768                 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJson;
769                 if (pushPolicyHandler.preSafetyCheck(updatedGroup, XACMLPapServlet.getConfigHome())) {
770                     LOGGER.debug("Precheck Successful.");
771                 }
772                 try {
773                     papEngine.updateGroup((StdPDPGroup) objectFromJson);
774                 } catch (PAPException e) {
775                     LOGGER.error(e);
776                 }
777                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
778                 if (LOGGER.isDebugEnabled()) {
779                     LOGGER.debug("Group '" + group.getId() + "' updated");
780                 }
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);
790                 return;
791             }
792         } catch (PAPException e) {
793             LOGGER.debug(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());
799             return;
800         }
801     }
802
803     /**
804      * Requests from the Admin Console to delete/remove items.
805      *
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.
812      */
813     public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
814             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
815         PolicyDBDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
816         try {
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);
821             if (group == null) {
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 + "'");
827                 return;
828             }
829             // determine the operation needed based on the parameters in the
830             // request
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");
839                 return;
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);
859                 return;
860             } else if (request.getParameter("pipId") != null) {
861                 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for
862                 // given engine
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");
868                 return;
869             } else {
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) {
875                     try {
876                         moveToGroup = papEngine.getGroup(moveToGroupId);
877                     } catch (PAPException e) {
878                         LOGGER.error(e);
879                     }
880                 }
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
889                 // changed
890                 for (OnapPDP pdp : movedPdps) {
891                     getPapInstance().pdpChanged(pdp, loggingContext);
892                 }
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);
900                 return;
901             }
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());
908             return;
909         }
910     }
911
912     private void deleteGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group,
913             OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException {
914         try {
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());
921         }
922     }
923
924     private void removePdpFromGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp,
925             PAPPolicyEngine papEngine) throws PAPException {
926         try {
927             removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
928             papEngine.removePDP(pdp);
929         } catch (Exception e) {
930             throw new PAPException(e);
931         }
932     }
933
934     private XACMLPapServlet getPapInstance() {
935         return new XACMLPapServlet();
936     }
937
938     private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
939         try {
940             mapper.writeValue(response.getOutputStream(), value);
941         } catch (Exception e) {
942             LOGGER.error(e);
943         }
944     }
945
946     private void setResponseError(HttpServletResponse response, int responseCode, String message) {
947         try {
948             if (message != null && !message.isEmpty()) {
949                 response.sendError(responseCode, message);
950             }
951         } catch (IOException e) {
952             LOGGER.error("Error setting Error response Header ", e);
953         }
954         return;
955     }
956 }