New junits and bug fixes
[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,
189                                     XACMLPapServlet.getConfigHome())) {
190                                 LOGGER.debug("Precheck Successful.");
191                             }
192                         }
193
194                         // delete temporary policy file from the bin directory
195                         Files.deleteIfExists(Paths.get(policyId));
196
197                     } catch (Exception e) {
198                         addPolicyToGroupTransaction.rollbackTransaction();
199                         String message = "Policy '" + policyName + "' not copied to group '" + groupId + "': " + e;
200                         // for fixing Header Manipulation of Fortify issue
201                         if (!message.matches(REGEX)) {
202                             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
203                             response.addHeader(ERROR, ADD_GROUP_ERROR);
204                             response.addHeader(MESSAGE, "Policy Id is not valid");
205                             return;
206                         }
207                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " " + message);
208                         loggingContext.transactionEnded();
209                         PolicyLogger.audit(TRANSACTIONFAILED);
210                         if (apiflag != null) {
211                             response.addHeader(ERROR, "policyCopyError");
212                             response.addHeader(MESSAGE, message);
213                             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
214                         } else {
215                             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
216                         }
217                         return;
218                     }
219                 }
220
221                 /*
222                  * If request comes from the API we need to run the PolicyDBDao updateGroup() to notify other paps of
223                  * the change. The GUI does this from the POLICY-SDK-APP code.
224                  */
225
226                 // Get new transaction to perform updateGroup()
227                 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
228                 try {
229                     // Assume that this is an update of an existing PDP
230                     // Group
231                     loggingContext.setServiceName("PolicyEngineAPI:PAP.updateGroup");
232                     try {
233                         acPutTransaction.updateGroup(updatedGroup, "XACMLPapServlet.doACPut", userId);
234                     } catch (Exception e) {
235                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
236                                 " Error occurred when notifying PAPs of a group change: " + e);
237                         throw new PAPException(e.getMessage());
238                     }
239
240                     LOGGER.info("Calling updatGroup() with new group");
241                     papEngine.updateGroup(updatedGroup);
242
243                     LOGGER.info("Group - '" + updatedGroup.getId() + "' updated");
244
245                     // Commit transaction to send notification to other PAPs
246                     loggingContext.metricStarted();
247                     acPutTransaction.commitTransaction();
248                     loggingContext.metricEnded();
249                     PolicyLogger.metrics("XACMLPapServlet updateGroupsFromAPI commitTransaction");
250                     // Group changed to send notification to PDPs, which
251                     // might include changing the policies
252                     getPapInstance().groupChanged(updatedGroup, loggingContext);
253                     loggingContext.transactionEnded();
254                     LOGGER.info(SUCCESS);
255                 } catch (Exception e) {
256                     acPutTransaction.rollbackTransaction();
257                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " API PUT exception");
258                     loggingContext.transactionEnded();
259                     PolicyLogger.audit(TRANSACTIONFAILED);
260                     String message = XACMLErrorConstants.ERROR_PROCESS_FLOW
261                             + "Exception occurred when updating the group from API.";
262                     LOGGER.error(message);
263                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
264                     response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
265                     response.addHeader(ERROR, ADD_GROUP_ERROR);
266                     response.addHeader(MESSAGE, message);
267                     return;
268                 }
269                 // policy file copied ok and the Group was updated on the PDP
270                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
271                 response.addHeader("operation", "push");
272                 response.addHeader(POLICYID, policyName);
273                 response.addHeader("groupId", groupId);
274
275                 LOGGER.info("policy '" + policyName + "' copied to directory for group '" + groupId + "'");
276                 loggingContext.transactionEnded();
277                 auditLogger.info(SUCCESS);
278                 LOGGER.info(TRANSENDED);
279
280                 return;
281             } else if (request.getParameter("default") != null) {
282                 // Args: group=<groupId> default=true <= make default
283                 // change the current default group to be the one identified in
284                 // the request.
285                 loggingContext.setServiceName("AC:PAP.setDefaultGroup");
286                 // This is a POST operation rather than a PUT "update group"
287                 // because of the side-effect that the current default group is
288                 // also changed.
289                 // It should never be the case that multiple groups are
290                 // currently marked as the default, but protect against that
291                 // anyway.
292                 PolicyDBDaoTransaction setDefaultGroupTransaction =
293                         XACMLPapServlet.getPolicyDbDao().getNewTransaction();
294                 try {
295                     setDefaultGroupTransaction.changeDefaultGroup(group, PAPSERVLETDOACPOST);
296                     papEngine.setDefaultGroup(group);
297                     loggingContext.metricStarted();
298                     setDefaultGroupTransaction.commitTransaction();
299                     loggingContext.metricEnded();
300                     PolicyLogger.metrics(ACPOSTCOMMITTRANS);
301                 } catch (Exception e) {
302                     setDefaultGroupTransaction.rollbackTransaction();
303                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " Unable to set group");
304                     loggingContext.transactionEnded();
305                     PolicyLogger.audit(TRANSACTIONFAILED);
306                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
307                             "Unable to set group '" + groupId + "' to default");
308                     return;
309                 }
310                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
311                 if (LOGGER.isDebugEnabled()) {
312                     LOGGER.debug("Group- '" + groupId + "' set to be default");
313                 }
314                 auditLogger.info(SUCCESS);
315                 LOGGER.info(TRANSENDED);
316                 return;
317             } else if (request.getParameter("pdpId") != null) {
318                 doAcPostTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
319                 // Args: group=<groupId> pdpId=<pdpId> <= move PDP to group
320                 loggingContext.setServiceName("AC:PAP.movePDP");
321                 String pdpId = request.getParameter("pdpId");
322                 OnapPDP pdp = papEngine.getPDP(pdpId);
323                 OnapPDPGroup originalGroup = papEngine.getPDPGroup(pdp);
324                 try {
325                     doAcPostTransaction.movePdp(pdp, group, PAPSERVLETDOACPOST);
326                 } catch (Exception e) {
327                     doAcPostTransaction.rollbackTransaction();
328                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
329                             " Error while moving pdp in the database: " + "pdp=" + pdp.getId() + ",to group="
330                                     + group.getId());
331                     throw new PAPException(e.getMessage());
332                 }
333                 papEngine.movePDP(pdp, group);
334                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
335                 if (LOGGER.isDebugEnabled()) {
336                     LOGGER.debug(
337                             "PDP - '" + pdp.getId() + "' moved to group - '" + group.getId() + "' set to be default");
338                 }
339                 // update the status of both the original group and the new one
340                 ((StdPDPGroup) originalGroup).resetStatus();
341                 ((StdPDPGroup) group).resetStatus();
342                 // Need to notify the PDP that it's config may have changed
343                 getPapInstance().pdpChanged(pdp, loggingContext);
344                 loggingContext.metricStarted();
345                 doAcPostTransaction.commitTransaction();
346                 loggingContext.metricEnded();
347                 PolicyLogger.metrics(ACPOSTCOMMITTRANS);
348                 loggingContext.transactionEnded();
349                 auditLogger.info(SUCCESS);
350                 PolicyLogger.audit(TRANSENDED);
351                 return;
352             }
353         } catch (PAPException e) {
354             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC POST exception");
355             loggingContext.transactionEnded();
356             PolicyLogger.audit(TRANSACTIONFAILED);
357             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
358             return;
359         }
360     }
361
362     /**
363      * Requests from the Admin Console to GET info about the Groups and PDPs.
364      *
365      * @param request the request
366      * @param response the response
367      * @param groupId the group id
368      * @param loggingContext the logging context
369      * @param papEngine the pap engine
370      * @throws IOException Signals that an I/O exception has occurred.
371      */
372     public void doAcGet(HttpServletRequest request, HttpServletResponse response, String groupId,
373             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
374         try {
375             String parameterDefault = request.getParameter("default");
376             String pdpId = request.getParameter("pdpId");
377             String pdpGroup = request.getParameter("getPDPGroup");
378             if ("".equals(groupId)) {
379                 // request IS from AC but does not identify a group by name
380                 if (parameterDefault != null) {
381                     // Request is for the Default group (whatever its id)
382                     loggingContext.setServiceName("AC:PAP.getDefaultGroup");
383                     OnapPDPGroup group = papEngine.getDefaultGroup();
384                     // convert response object to JSON and include in the
385                     // response
386                     mapperWriteValue(new ObjectMapper(), response, group);
387                     if (LOGGER.isDebugEnabled()) {
388                         LOGGER.debug("GET Default group req from '" + request.getRequestURL() + "'");
389                     }
390                     response.setStatus(HttpServletResponse.SC_OK);
391                     response.setHeader("content-type", "application/json");
392                     try {
393                         response.getOutputStream().close();
394                     } catch (IOException e) {
395                         LOGGER.error(e);
396                     }
397                     loggingContext.transactionEnded();
398                     auditLogger.info(SUCCESS);
399                     PolicyLogger.audit(TRANSENDED);
400                     return;
401                 } else if (pdpId != null) {
402                     // Request is related to a PDP
403                     if (pdpGroup == null) {
404                         // Request is for the (unspecified) group containing a
405                         // given PDP
406                         loggingContext.setServiceName("AC:PAP.getPDP");
407                         OnapPDP pdp = null;
408                         try {
409                             pdp = papEngine.getPDP(pdpId);
410                         } catch (PAPException e) {
411                             LOGGER.error(e);
412                         }
413                         // convert response object to JSON and include in the
414                         // response
415                         mapperWriteValue(new ObjectMapper(), response, pdp);
416                         if (LOGGER.isDebugEnabled()) {
417                             LOGGER.debug("GET pdp '" + pdpId + "' req from '" + request.getRequestURL() + "'");
418                         }
419                         response.setStatus(HttpServletResponse.SC_OK);
420                         response.setHeader("content-type", "application/json");
421                         try {
422                             response.getOutputStream().close();
423                         } catch (IOException e) {
424                             LOGGER.error(e);
425                         }
426                         loggingContext.transactionEnded();
427                         auditLogger.info(SUCCESS);
428                         PolicyLogger.audit(TRANSENDED);
429                         return;
430                     } else {
431                         // Request is for the group containing a given PDP
432                         loggingContext.setServiceName("AC:PAP.getGroupForPDP");
433                         OnapPDPGroup group = null;
434                         try {
435                             OnapPDP pdp = papEngine.getPDP(pdpId);
436                             group = papEngine.getPDPGroup(pdp);
437                         } catch (PAPException e) {
438                             LOGGER.error(e);
439                         }
440                         // convert response object to JSON and include in the
441                         // response
442                         mapperWriteValue(new ObjectMapper(), response, group);
443                         if (LOGGER.isDebugEnabled()) {
444                             LOGGER.debug("GET PDP '" + pdpId + "' Group req from '" + request.getRequestURL() + "'");
445                         }
446                         response.setStatus(HttpServletResponse.SC_OK);
447                         response.setHeader("content-type", "application/json");
448                         try {
449                             response.getOutputStream().close();
450                         } catch (IOException e) {
451                             LOGGER.error(e);
452                         }
453                         loggingContext.transactionEnded();
454                         auditLogger.info(SUCCESS);
455                         PolicyLogger.audit(TRANSENDED);
456                         return;
457                     }
458                 } else {
459                     // request is for top-level properties about all groups
460                     loggingContext.setServiceName("AC:PAP.getAllGroups");
461                     Set<OnapPDPGroup> groups = null;
462                     try {
463                         groups = papEngine.getOnapPDPGroups();
464                     } catch (PAPException e) {
465                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
466                         loggingContext.transactionEnded();
467                         PolicyLogger.audit(TRANSACTIONFAILED);
468                         setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
469                         return;
470                     }
471                     // convert response object to JSON and include in the
472                     // response
473                     mapperWriteValue(new ObjectMapper(), response, groups);
474                     if (LOGGER.isDebugEnabled()) {
475                         LOGGER.debug("GET All groups req");
476                     }
477                     response.setStatus(HttpServletResponse.SC_OK);
478                     response.setHeader("content-type", "application/json");
479                     try {
480                         response.getOutputStream().close();
481                     } catch (IOException e) {
482                         LOGGER.error(e);
483                     }
484                     loggingContext.transactionEnded();
485                     auditLogger.info(SUCCESS);
486                     PolicyLogger.audit(TRANSENDED);
487                     return;
488                 }
489             }
490             // for all other GET operations the group must exist before the
491             // operation can be done
492             OnapPDPGroup group = null;
493             try {
494                 group = papEngine.getGroup(groupId);
495             } catch (PAPException e) {
496                 LOGGER.error(e);
497             }
498             if (group == null) {
499                 String message = "Unknown groupId '" + groupId + "'";
500                 // for fixing Header Manipulation of Fortify issue
501                 if (!message.matches(REGEX)) {
502                     response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
503                     response.addHeader(ERROR, ADD_GROUP_ERROR);
504                     response.addHeader(MESSAGE, "Group Id is not valid");
505                     return;
506                 }
507                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
508                 loggingContext.transactionEnded();
509                 PolicyLogger.audit(TRANSACTIONFAILED);
510                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
511                 return;
512             }
513             // Figure out which request this is based on the parameters
514             String policyId = request.getParameter(POLICYID);
515             if (policyId != null) {
516                 // retrieve a policy
517                 loggingContext.setServiceName("AC:PAP.getPolicy");
518                 // convert response object to JSON and include in the response
519                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " GET Policy not implemented");
520                 loggingContext.transactionEnded();
521                 PolicyLogger.audit(TRANSACTIONFAILED);
522                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "GET Policy not implemented");
523             } else {
524                 // No other parameters, so return the identified Group
525                 loggingContext.setServiceName("AC:PAP.getGroup");
526                 // convert response object to JSON and include in the response
527                 mapperWriteValue(new ObjectMapper(), response, group);
528                 if (LOGGER.isDebugEnabled()) {
529                     LOGGER.debug("GET group '" + group.getId() + "' req from '" + request.getRequestURL() + "'");
530                 }
531                 response.setStatus(HttpServletResponse.SC_OK);
532                 response.setHeader("content-type", "application/json");
533                 try {
534                     response.getOutputStream().close();
535                 } catch (IOException e) {
536                     LOGGER.error(e);
537                 }
538                 loggingContext.transactionEnded();
539                 auditLogger.info(SUCCESS);
540                 PolicyLogger.audit(TRANSENDED);
541                 return;
542             }
543             // Currently there are no other GET calls from the AC.
544             // The AC uses the "GET All Groups" operation to fill its local
545             // cache and uses that cache for all other GETs without calling the
546             // PAP.
547             // Other GETs that could be called:
548             // Specific Group (groupId=<groupId>)
549             // A Policy (groupId=<groupId> policyId=<policyId>)
550             // A PDP (groupId=<groupId> pdpId=<pdpId>)
551             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " UNIMPLEMENTED ");
552             loggingContext.transactionEnded();
553             PolicyLogger.audit(TRANSACTIONFAILED);
554             setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
555         } catch (PAPException e) {
556             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC Get exception");
557             loggingContext.transactionEnded();
558             PolicyLogger.audit(TRANSACTIONFAILED);
559             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
560             return;
561         }
562     }
563
564     /**
565      * Requests from the Admin Console to create new items or update existing ones.
566      *
567      * @param request the request
568      * @param response the response
569      * @param groupId the group id
570      * @param loggingContext the logging context
571      * @param papEngine the pap engine
572      * @throws IOException Signals that an I/O exception has occurred.
573      */
574     public void doAcPut(HttpServletRequest request, HttpServletResponse response, String groupId,
575             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
576         PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
577         try {
578             String userId = request.getParameter("userId");
579             // for PUT operations the group may or may not need to exist before
580             // the operation can be done
581             OnapPDPGroup group = papEngine.getGroup(groupId);
582             // determine the operation needed based on the parameters in the
583             // request
584             // for remaining operations the group must exist before the
585             // operation can be done
586             if (group == null) {
587                 String message = "Unknown groupId '" + groupId + "'";
588                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
589                 loggingContext.transactionEnded();
590                 PolicyLogger.audit(TRANSACTIONFAILED);
591                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, message);
592                 acPutTransaction.rollbackTransaction();
593                 return;
594             }
595             if (request.getParameter("policy") != null) {
596                 // group=<groupId> policy=<policyId> contents=policy file <=
597                 // Create new policy file in group dir, or replace it if it
598                 // already exists (do not touch properties)
599                 loggingContext.setServiceName("AC:PAP.putPolicy");
600                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
601                         + " PARTIALLY IMPLEMENTED!!!  ACTUAL CHANGES SHOULD BE MADE BY PAP SERVLET!!! ");
602                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
603                 loggingContext.transactionEnded();
604                 PolicyLogger.audit(TRANSACTIONFAILED);
605                 auditLogger.info(SUCCESS);
606                 PolicyLogger.audit(TRANSENDED);
607                 acPutTransaction.rollbackTransaction();
608                 return;
609             } else if (request.getParameter("pdpId") != null) {
610                 // ARGS: group=<groupId> pdpId=<pdpId/URL> <= create a new PDP
611                 // or Update an Existing one
612                 String pdpId = request.getParameter("pdpId");
613                 if (papEngine.getPDP(pdpId) == null) {
614                     loggingContext.setServiceName("AC:PAP.createPDP");
615                 } else {
616                     loggingContext.setServiceName("AC:PAP.updatePDP");
617                 }
618                 // get the request content into a String
619                 String json = null;
620                 // read the inputStream into a buffer (trick found online scans
621                 // entire input looking for end-of-file)
622                 try {
623                     Scanner scanner = new Scanner(request.getInputStream());
624                     scanner.useDelimiter("\\A");
625                     json = scanner.hasNext() ? scanner.next() : "";
626                     scanner.close();
627                 } catch (IOException e) {
628                     LOGGER.error(e);
629                 }
630                 LOGGER.info("JSON request from AC: " + json);
631                 // convert Object sent as JSON into local object
632                 ObjectMapper mapper = new ObjectMapper();
633                 Object objectFromJson = null;
634                 try {
635                     objectFromJson = mapper.readValue(json, StdPDP.class);
636                 } catch (Exception e) {
637                     LOGGER.error(e);
638                 }
639                 if (pdpId == null || objectFromJson == null || !(objectFromJson instanceof StdPDP)
640                         || ((StdPDP) objectFromJson).getId() == null
641                         || !((StdPDP) objectFromJson).getId().equals(pdpId)) {
642                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " PDP new/update had bad input. pdpId=" + pdpId
643                             + " objectFromJSON=" + objectFromJson);
644                     loggingContext.transactionEnded();
645                     PolicyLogger.audit(TRANSACTIONFAILED);
646                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
647                             "Bad input pdpid for object:" + objectFromJson);
648                 }
649                 StdPDP pdp = (StdPDP) objectFromJson;
650                 if (pdp != null) {
651                     OnapPDP origPdp = null;
652                     try {
653                         origPdp = papEngine.getPDP(pdpId);
654                     } catch (PAPException e) {
655                         LOGGER.error(e);
656                     }
657                     if (origPdp == null) {
658                         // this is a request to create a new PDP object
659                         try {
660                             acPutTransaction.addPdpToGroup(pdp.getId(), group.getId(), pdp.getName(),
661                                     pdp.getDescription(), pdp.getJmxPort(), "XACMLPapServlet.doACPut");
662                             papEngine.newPDP(pdp.getId(), group, pdp.getName(), pdp.getDescription(), pdp.getJmxPort());
663                         } catch (Exception e) {
664                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
665                                     " Error while adding pdp to group in the database: " + "pdp=" + (pdp.getId())
666                                             + ",to group=" + group.getId());
667                             throw new PAPException(e.getMessage());
668                         }
669                     } else {
670                         // this is a request to update the pdp
671                         try {
672                             acPutTransaction.updatePdp(pdp, "XACMLPapServlet.doACPut");
673                             papEngine.updatePDP(pdp);
674                         } catch (Exception e) {
675                             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET,
676                                     " Error while updating pdp in the database: " + "pdp=" + pdp.getId());
677                             throw new PAPException(e.getMessage());
678                         }
679                     }
680                     response.setStatus(HttpServletResponse.SC_NO_CONTENT);
681                     if (LOGGER.isDebugEnabled()) {
682                         LOGGER.debug("PDP '" + pdpId + "' created/updated");
683                     }
684                     // adjust the group's state including the new PDP
685                     ((StdPDPGroup) group).resetStatus();
686                     // this might affect the PDP, so notify it of the change
687                     getPapInstance().pdpChanged(pdp, loggingContext);
688                     loggingContext.metricStarted();
689                     acPutTransaction.commitTransaction();
690                     loggingContext.metricEnded();
691                     PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
692                     loggingContext.transactionEnded();
693                     auditLogger.info(SUCCESS);
694                     PolicyLogger.audit(TRANSENDED);
695                     return;
696                 } else {
697                     try {
698                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, XACMLPAPSERVLET,
699                                 " Error while adding pdp to group in the database: " + "pdp=null" + ",to group="
700                                         + group.getId());
701                         throw new PAPException("PDP is null");
702                     } catch (Exception e) {
703                         throw new PAPException("PDP is null" + e.getMessage() + e);
704                     }
705                 }
706             } else if (request.getParameter("pipId") != null) {
707                 // group=<groupId> pipId=<pipEngineId> contents=pip properties
708                 // <= add a PIP to pip config, or replace it if it already
709                 // exists (lenient operation)
710                 loggingContext.setServiceName("AC:PAP.putPIP");
711                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
712                 loggingContext.transactionEnded();
713                 PolicyLogger.audit(TRANSACTIONFAILED);
714                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
715                 acPutTransaction.rollbackTransaction();
716                 return;
717             } else {
718                 // Assume that this is an update of an existing PDP Group
719                 // ARGS: group=<groupId> <= Update an Existing Group
720                 loggingContext.setServiceName("AC:PAP.updateGroup");
721                 // get the request content into a String
722                 String json = null;
723                 // read the inputStream into a buffer (trick found online scans
724                 // entire input looking for end-of-file)
725                 try {
726                     Scanner scanner = new Scanner(request.getInputStream());
727                     scanner.useDelimiter("\\A");
728                     json = scanner.hasNext() ? scanner.next() : "";
729                     scanner.close();
730                 } catch (IOException e) {
731                     LOGGER.error(e);
732                 }
733                 LOGGER.info("JSON request from AC: " + json);
734                 // convert Object sent as JSON into local object
735                 ObjectMapper mapper = new ObjectMapper();
736                 Object objectFromJson = null;
737                 try {
738                     objectFromJson = mapper.readValue(json, StdPDPGroup.class);
739                 } catch (Exception e) {
740                     LOGGER.error(e);
741                 }
742                 if (objectFromJson == null || !(objectFromJson instanceof StdPDPGroup)
743                         || !((StdPDPGroup) objectFromJson).getId().equals(group.getId())) {
744                     PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id="
745                             + group.getId() + " objectFromJSON=" + objectFromJson);
746                     loggingContext.transactionEnded();
747                     PolicyLogger.audit(TRANSACTIONFAILED);
748                     setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
749                             "Bad input id for object:" + objectFromJson);
750                 }
751                 // The Path on the PAP side is not carried on the RESTful
752                 // interface with the AC
753                 // (because it is local to the PAP)
754                 // so we need to fill that in before submitting the group for
755                 // update
756                 if (objectFromJson != null) {
757                     ((StdPDPGroup) objectFromJson).setDirectory(((StdPDPGroup) group).getDirectory());
758                 }
759                 try {
760                     if ("delete".equals(((StdPDPGroup) objectFromJson).getOperation())) {
761                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doDelete", userId);
762                     } else {
763                         acPutTransaction.updateGroup((StdPDPGroup) objectFromJson, "XACMLPapServlet.doACPut", userId);
764                     }
765                 } catch (Exception e) {
766                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database: "
767                             + "group=" + group.getId());
768                     LOGGER.error(e);
769                     throw new PAPException(e.getMessage());
770                 }
771
772                 PushPolicyHandler pushPolicyHandler = PushPolicyHandler.getInstance();
773                 OnapPDPGroup updatedGroup = (StdPDPGroup) objectFromJson;
774                 if (pushPolicyHandler.preSafetyCheck(updatedGroup, XACMLPapServlet.getConfigHome())) {
775                     LOGGER.debug("Precheck Successful.");
776                 }
777                 try {
778                     papEngine.updateGroup((StdPDPGroup) objectFromJson);
779                 } catch (PAPException e) {
780                     LOGGER.error(e);
781                 }
782                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
783                 if (LOGGER.isDebugEnabled()) {
784                     LOGGER.debug("Group '" + group.getId() + "' updated");
785                 }
786                 loggingContext.metricStarted();
787                 acPutTransaction.commitTransaction();
788                 loggingContext.metricEnded();
789                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
790                 // Group changed, which might include changing the policies
791                 getPapInstance().groupChanged(group, loggingContext);
792                 loggingContext.transactionEnded();
793                 auditLogger.info(SUCCESS);
794                 PolicyLogger.audit(TRANSENDED);
795                 return;
796             }
797         } catch (PAPException e) {
798             LOGGER.debug(e);
799             acPutTransaction.rollbackTransaction();
800             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC PUT exception");
801             loggingContext.transactionEnded();
802             PolicyLogger.audit(TRANSACTIONFAILED);
803             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
804             return;
805         }
806     }
807
808     /**
809      * Requests from the Admin Console to delete/remove items.
810      *
811      * @param request the request
812      * @param response the response
813      * @param groupId the group id
814      * @param loggingContext the logging context
815      * @param papEngine the pap engine
816      * @throws IOException Signals that an I/O exception has occurred.
817      */
818     public void doAcDelete(HttpServletRequest request, HttpServletResponse response, String groupId,
819             ONAPLoggingContext loggingContext, PAPPolicyEngine papEngine) throws IOException {
820         PolicyDBDaoTransaction removePdpOrGroupTransaction = XACMLPapServlet.getPolicyDbDao().getNewTransaction();
821         try {
822             // for all DELETE operations the group must exist before the
823             // operation can be done
824             loggingContext.setServiceName("AC:PAP.delete");
825             OnapPDPGroup group = papEngine.getGroup(groupId);
826             if (group == null) {
827                 String message = "Unknown groupId '" + groupId + "'";
828                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
829                 loggingContext.transactionEnded();
830                 PolicyLogger.audit(TRANSACTIONFAILED);
831                 setResponseError(response, HttpServletResponse.SC_NOT_FOUND, "Unknown groupId '" + groupId + "'");
832                 removePdpOrGroupTransaction.rollbackTransaction();
833                 return;
834             }
835             // determine the operation needed based on the parameters in the
836             // request
837             if (request.getParameter("policy") != null) {
838                 // group=<groupId> policy=<policyId> [delete=<true|false>] <=
839                 // delete policy file from group
840                 loggingContext.setServiceName("AC:PAP.deletePolicy");
841                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
842                 loggingContext.transactionEnded();
843                 PolicyLogger.audit(TRANSACTIONFAILED);
844                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
845                 removePdpOrGroupTransaction.rollbackTransaction();
846                 return;
847             } else if (request.getParameter("pdpId") != null) {
848                 // ARGS: group=<groupId> pdpId=<pdpId> <= delete PDP
849                 String pdpId = request.getParameter("pdpId");
850                 OnapPDP pdp = papEngine.getPDP(pdpId);
851                 removePdpFromGroup(removePdpOrGroupTransaction, pdp, papEngine);
852                 // adjust the status of the group, which may have changed when
853                 // we removed this PDP
854                 ((StdPDPGroup) group).resetStatus();
855                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
856                 // update the PDP and tell it that it has NO Policies (which
857                 // prevents it from serving PEP Requests)
858                 getPapInstance().pdpChanged(pdp, loggingContext);
859                 loggingContext.metricStarted();
860                 removePdpOrGroupTransaction.commitTransaction();
861                 loggingContext.metricEnded();
862                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
863                 loggingContext.transactionEnded();
864                 auditLogger.info(SUCCESS);
865                 PolicyLogger.audit(TRANSENDED);
866                 return;
867             } else if (request.getParameter("pipId") != null) {
868                 // group=<groupId> pipId=<pipEngineId> <= delete PIP config for
869                 // given engine
870                 loggingContext.setServiceName("AC:PAP.deletePIPConfig");
871                 PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " UNIMPLEMENTED");
872                 loggingContext.transactionEnded();
873                 PolicyLogger.audit(TRANSACTIONFAILED);
874                 setResponseError(response, HttpServletResponse.SC_BAD_REQUEST, "UNIMPLEMENTED");
875                 removePdpOrGroupTransaction.rollbackTransaction();
876                 return;
877             } else {
878                 // ARGS: group=<groupId> movePDPsToGroupId=<movePDPsToGroupId>
879                 // <= delete a group and move all its PDPs to the given group
880                 String moveToGroupId = request.getParameter("movePDPsToGroupId");
881                 OnapPDPGroup moveToGroup = null;
882                 if (moveToGroupId != null) {
883                     try {
884                         moveToGroup = papEngine.getGroup(moveToGroupId);
885                     } catch (PAPException e) {
886                         LOGGER.error(e);
887                     }
888                 }
889                 // get list of PDPs in the group being deleted so we can notify
890                 // them that they got changed
891                 Set<OnapPDP> movedPdps = new HashSet<>();
892                 movedPdps.addAll(group.getOnapPdps());
893                 // do the move/remove
894                 deleteGroup(removePdpOrGroupTransaction, group, moveToGroup, papEngine);
895                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
896                 // notify any PDPs in the removed set that their config may have
897                 // changed
898                 for (OnapPDP pdp : movedPdps) {
899                     getPapInstance().pdpChanged(pdp, loggingContext);
900                 }
901                 loggingContext.metricStarted();
902                 removePdpOrGroupTransaction.commitTransaction();
903                 loggingContext.metricEnded();
904                 PolicyLogger.metrics("XACMLPapServlet doACPut commitTransaction");
905                 loggingContext.transactionEnded();
906                 auditLogger.info(SUCCESS);
907                 PolicyLogger.audit(TRANSENDED);
908                 return;
909             }
910         } catch (PAPException e) {
911             removePdpOrGroupTransaction.rollbackTransaction();
912             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, XACMLPAPSERVLET, " AC DELETE exception");
913             loggingContext.transactionEnded();
914             PolicyLogger.audit(TRANSACTIONFAILED);
915             setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
916             return;
917         }
918     }
919
920     private void deleteGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDPGroup group,
921             OnapPDPGroup moveToGroup, PAPPolicyEngine papEngine) throws PAPException {
922         try {
923             removePdpOrGroupTransaction.deleteGroup(group, moveToGroup, "XACMLPapServlet.doACDelete");
924             papEngine.removeGroup(group, moveToGroup);
925         } catch (Exception e) {
926             PolicyLogger.error(MessageCodes.ERROR_UNKNOWN, e, XACMLPAPSERVLET,
927                     " Failed to delete PDP Group. Exception");
928             throw new PAPException(e.getMessage());
929         }
930     }
931
932     private void removePdpFromGroup(PolicyDBDaoTransaction removePdpOrGroupTransaction, OnapPDP pdp,
933             PAPPolicyEngine papEngine) throws PAPException {
934         try {
935             removePdpOrGroupTransaction.removePdpFromGroup(pdp.getId(), "XACMLPapServlet.doACDelete");
936             papEngine.removePDP(pdp);
937         } catch (Exception e) {
938             throw new PAPException(e);
939         }
940     }
941
942     private XACMLPapServlet getPapInstance() {
943         return new XACMLPapServlet();
944     }
945
946     private static void mapperWriteValue(ObjectMapper mapper, HttpServletResponse response, Object value) {
947         try {
948             mapper.writeValue(response.getOutputStream(), value);
949         } catch (Exception e) {
950             LOGGER.error(e);
951         }
952     }
953
954     private void setResponseError(HttpServletResponse response, int responseCode, String message) {
955         try {
956             if (message != null && !message.isEmpty()) {
957                 response.sendError(responseCode, message);
958             }
959         } catch (IOException e) {
960             LOGGER.error("Error setting Error response Header ", e);
961         }
962         return;
963     }
964 }