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