ONAP-REST DAO Sonar/Checkstyle clean and knock-on
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / handler / DeleteHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pap.xacml.rest.handler;
23
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.api.pap.PDPPolicy;
26 import com.att.research.xacml.util.XACMLProperties;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.util.Arrays;
31 import java.util.List;
32
33 import javax.script.SimpleBindings;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
37 import org.apache.commons.lang3.StringUtils;
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.XACMLPapServlet;
44 import org.onap.policy.pap.xacml.rest.components.PolicyDbDaoTransaction;
45 import org.onap.policy.pap.xacml.rest.elk.client.PolicyElasticSearchController;
46 import org.onap.policy.pap.xacml.rest.model.RemoveGroupPolicy;
47 import org.onap.policy.pap.xacml.rest.util.JPAUtils;
48 import org.onap.policy.rest.adapter.PolicyRestAdapter;
49 import org.onap.policy.rest.dao.CommonClassDao;
50 import org.onap.policy.rest.jpa.PolicyEntity;
51 import org.onap.policy.rest.jpa.PolicyVersion;
52 import org.onap.policy.utils.PolicyUtils;
53 import org.onap.policy.xacml.api.XACMLErrorConstants;
54 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
55 import org.onap.policy.xacml.std.pap.StdPAPPolicy;
56 import org.onap.policy.xacml.std.pap.StdPDPGroup;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.stereotype.Component;
59
60 @Component
61 public class DeleteHandler {
62
63     private static CommonClassDao commonClassDao;
64
65     @Autowired
66     public DeleteHandler(CommonClassDao commonClassDao) {
67         DeleteHandler.commonClassDao = commonClassDao;
68     }
69
70     public DeleteHandler() {
71         // Default Constructor
72     }
73
74     private OnapPDPGroup newgroup;
75     private static final Logger LOGGER = FlexLogger.getLogger(DeleteHandler.class);
76     private static final String POLICY_IN_PDP = "PolicyInPDP";
77     private static final String ERROR = "error";
78     private static final String MESSAGE = "message";
79     private static final String UNKNOWN = "unknown";
80     private static final String SUCCESS = "success";
81     private static final String OPERATION = "operation";
82     private static final String CONFIG = "Config_";
83     private static final String REGEX = "[0-9a-zA-Z._]*";
84     private static final String DELETE = "delete";
85     private static final String ACTION = "Action_";
86
87     /**
88      * Do API delete from PAP.
89      *
90      * @param request the request
91      * @param response the response
92      * @throws IOException Signals that an I/O exception has occurred.
93      */
94     public void doApiDeleteFromPap(HttpServletRequest request, HttpServletResponse response) throws IOException {
95         // get the request content into a String
96         String json = null;
97         java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
98         scanner.useDelimiter("\\A");
99         json = scanner.hasNext() ? scanner.next() : "";
100         scanner.close();
101         PolicyLogger.info("JSON request from API to Delete Policy from the PAP: " + json);
102         // convert Object sent as JSON into local object
103         StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
104         String policyName = policy.getPolicyName();
105         boolean policyVersionDeleted = false;
106         String removeXmlExtension;
107         int currentVersion;
108         String removeVersionExtension;
109         String splitPolicyName = null;
110         String[] split = null;
111         String status = ERROR;
112         PolicyEntity policyEntity = null;
113         JPAUtils jpaUtils = null;
114
115         try {
116             jpaUtils = JPAUtils.getJPAUtilsInstance();
117         } catch (Exception e) {
118             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "doAPIDeleteFromPAP",
119                     " Could not create JPAUtils instance on the PAP");
120             response.addHeader(ERROR, "jpautils");
121             response.addHeader(OPERATION, DELETE);
122             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
123             return;
124         }
125         if (jpaUtils.dbLockdownIgnoreErrors()) {
126             PolicyLogger.warn("Policies are locked down");
127             response.addHeader(OPERATION, DELETE);
128             response.addHeader("lockdown", "true");
129             response.setStatus(HttpServletResponse.SC_ACCEPTED);
130             return;
131         }
132         String policyEntityQuery = null;
133         try {
134             if (policyName.endsWith(".xml")) {
135                 removeXmlExtension = policyName.replace(".xml", "");
136                 currentVersion =
137                         Integer.parseInt(removeXmlExtension.substring(removeXmlExtension.lastIndexOf('.') + 1));
138                 removeVersionExtension = removeXmlExtension.substring(0, removeXmlExtension.lastIndexOf('.'));
139                 boolean queryCheck = true;
140                 if ("All Versions".equalsIgnoreCase(policy.getDeleteCondition())) {
141                     if (policyName.contains(CONFIG)) {
142                         splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
143                     } else if (policyName.contains(ACTION)) {
144                         splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
145                     } else if (policyName.contains("Decision_")) {
146                         splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
147                     }
148                     if (splitPolicyName != null) {
149                         split = splitPolicyName.split(":");
150                     } else {
151                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
152                                 + "Failed to delete the policy. Please, provide the valid policyname.");
153                         response.addHeader(ERROR, UNKNOWN);
154                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
155                         return;
156                     }
157                     policyEntityQuery =
158                             "SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope";
159                 } else if ("Current Version".equalsIgnoreCase(policy.getDeleteCondition())) {
160                     if (policyName.contains(CONFIG)) {
161                         splitPolicyName = policyName.replace(".Config_", ":Config_");
162                     } else if (policyName.contains(ACTION)) {
163                         splitPolicyName = policyName.replace(".Action_", ":Action_");
164                     } else if (policyName.contains("Decision_")) {
165                         splitPolicyName = policyName.replace(".Decision_", ":Decision_");
166                     }
167                     split = splitPolicyName.split(":");
168                     queryCheck = false;
169                     policyEntityQuery = "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope";
170                 }
171                 SimpleBindings params = new SimpleBindings();
172                 if (queryCheck) {
173                     params.put("pName", "%" + split[1] + "%");
174                 } else {
175                     params.put("pName", split[1]);
176                 }
177
178                 params.put("pScope", split[0]);
179                 List<?> peResult = commonClassDao.getDataByQuery(policyEntityQuery, params);
180                 if (!peResult.isEmpty()) {
181                     String getPolicyVersion = "Select p from PolicyVersion p where p.policyName=:pname";
182                     SimpleBindings pvParams = new SimpleBindings();
183                     pvParams.put("pname", removeVersionExtension.replace(".", File.separator));
184                     List<?> pvResult = commonClassDao.getDataByQuery(getPolicyVersion, pvParams);
185                     PolicyVersion polVersion = (PolicyVersion) pvResult.get(0);
186                     int newVersion = 0;
187                     if ("All Versions".equalsIgnoreCase(policy.getDeleteCondition())) {
188                         boolean groupCheck = checkPolicyGroupEntity(peResult);
189                         if (!groupCheck) {
190                             for (Object peData : peResult) {
191                                 policyEntity = (PolicyEntity) peData;
192                                 status = deletePolicyEntityData(policyEntity);
193                             }
194                         } else {
195                             status = POLICY_IN_PDP;
196                         }
197                         switch (status) {
198                             case ERROR:
199                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
200                                         + "Exception Occured while deleting the Entity from Database.");
201                                 response.addHeader(ERROR, UNKNOWN);
202                                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
203                                 return;
204                             case POLICY_IN_PDP:
205                                 PolicyLogger.error(MessageCodes.GENERAL_WARNING
206                                         + "Policy can't be deleted, it is active in PDP Groups.");
207                                 response.addHeader(ERROR, POLICY_IN_PDP);
208                                 response.setStatus(HttpServletResponse.SC_CONFLICT);
209                                 return;
210                             default:
211                                 try {
212                                     policyVersionDeleted = true;
213                                     commonClassDao.delete(polVersion);
214                                 } catch (Exception e) {
215                                     LOGGER.error(e.getMessage(), e);
216                                     policyVersionDeleted = false;
217                                 }
218                                 break;
219                         }
220                     } else if ("Current Version".equalsIgnoreCase(policy.getDeleteCondition())) {
221                         boolean groupCheck = checkPolicyGroupEntity(peResult);
222                         if (!groupCheck) {
223                             policyEntity = (PolicyEntity) peResult.get(0);
224                             status = deletePolicyEntityData(policyEntity);
225                         } else {
226                             status = POLICY_IN_PDP;
227                         }
228
229                         if (ERROR.equals(status)) {
230                             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
231                                     + "Exception Occured while deleting the Entity from Database.");
232                             response.addHeader(ERROR, UNKNOWN);
233                             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
234                             return;
235                         } else if (POLICY_IN_PDP.equals(status)) {
236                             PolicyLogger.error(MessageCodes.GENERAL_WARNING
237                                     + "Policy can't be deleted, it is active in PDP Groups.");
238                             response.addHeader(ERROR, POLICY_IN_PDP);
239                             response.setStatus(HttpServletResponse.SC_CONFLICT);
240                             return;
241                         } else {
242                             if (currentVersion > 1) {
243                                 if (!peResult.isEmpty()) {
244                                     for (Object object : peResult) {
245                                         policyEntity = (PolicyEntity) object;
246                                         String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
247                                         int policyEntityVersion = Integer.parseInt(
248                                                 policyEntityName.substring(policyEntityName.lastIndexOf('.') + 1));
249                                         if (policyEntityVersion > newVersion) {
250                                             newVersion = policyEntityVersion - 1;
251                                         }
252                                     }
253                                 }
254                                 polVersion.setActiveVersion(newVersion);
255                                 polVersion.setHigherVersion(newVersion);
256                                 try {
257                                     policyVersionDeleted = true;
258                                     commonClassDao.save(polVersion);
259                                 } catch (Exception e) {
260                                     LOGGER.error(e.getMessage(), e);
261                                     policyVersionDeleted = false;
262                                 }
263                             } else {
264                                 try {
265                                     policyVersionDeleted = true;
266                                     commonClassDao.delete(polVersion);
267                                 } catch (Exception e) {
268                                     LOGGER.error(e.getMessage(), e);
269                                     policyVersionDeleted = false;
270                                 }
271                             }
272                         }
273                     }
274                 } else {
275                     PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
276                             + "Failed to delete the policy for an unknown reason.  Check the file system and other logs"
277                             + " for further information.");
278                     response.addHeader(ERROR, UNKNOWN);
279                     response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
280                     return;
281                 }
282             }
283         } catch (Exception e) {
284             PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
285             response.addHeader(ERROR, "deleteDB");
286             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
287             return;
288         }
289
290         if (policyVersionDeleted) {
291             response.setStatus(HttpServletResponse.SC_OK);
292             response.addHeader("successMapKey", SUCCESS);
293             response.addHeader(OPERATION, DELETE);
294         } else {
295             PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
296                     + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for "
297                     + "further information.");
298             response.addHeader(ERROR, UNKNOWN);
299             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
300         }
301     }
302
303     /**
304      * Delete policy entity data.
305      *
306      * @param policyEntity the policy entity
307      * @return the string
308      */
309     public static String deletePolicyEntityData(PolicyEntity policyEntity) {
310         PolicyElasticSearchController controller = new PolicyElasticSearchController();
311         PolicyRestAdapter policyData = new PolicyRestAdapter();
312         String policyName = policyEntity.getPolicyName();
313         try {
314             if (policyName.contains("CONFIG") || policyName.contains("Decision_MS_")) {
315                 commonClassDao.delete(policyEntity.getConfigurationData());
316             } else if (policyName.contains(ACTION)) {
317                 commonClassDao.delete(policyEntity.getActionBodyEntity());
318             }
319             String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
320             policyData.setNewFileName(searchPolicyName);
321             controller.deleteElk(policyData);
322             commonClassDao.delete(policyEntity);
323         } catch (Exception e) {
324             LOGGER.error(e.getMessage(), e);
325             return ERROR;
326         }
327         return SUCCESS;
328     }
329
330     /**
331      * Check policy group entity.
332      *
333      * @param peResult the pe result
334      * @return true, if successful
335      */
336     public static boolean checkPolicyGroupEntity(List<?> peResult) {
337         String groupEntityquery = "from PolicyGroupEntity where policyid = :policyEntityId";
338         for (Object peData : peResult) {
339             PolicyEntity policyEntity = (PolicyEntity) peData;
340             SimpleBindings geParams = new SimpleBindings();
341             geParams.put("policyEntityId", policyEntity.getPolicyId());
342             List<Object> groupobject = commonClassDao.getDataByQuery(groupEntityquery, geParams);
343             if (!groupobject.isEmpty()) {
344                 return true;
345             }
346         }
347         return false;
348     }
349
350     /**
351      * Do API delete from PDP.
352      *
353      * @param request the request
354      * @param response the response
355      * @param loggingContext the logging context
356      * @throws IOException Signals that an I/O exception has occurred.
357      */
358     public void doApiDeleteFromPdp(HttpServletRequest request, HttpServletResponse response,
359             OnapLoggingContext loggingContext) throws IOException {
360
361         String groupId = request.getParameter("groupId");
362
363         if (groupId != null && !groupId.matches(REGEX)) {
364             response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
365             response.addHeader(ERROR, ERROR);
366             response.addHeader(MESSAGE, "Group Id is not valid");
367             return;
368         }
369         String requestId = request.getHeader("X-ECOMP-RequestID");
370         String polName = request.getParameter("policyName");
371         LOGGER.info("JSON request from API to Delete Policy from the PDP - " + polName + " -RequestId - " + requestId);
372
373         // for PUT operations the group may or may not need to exist before the operation can be
374         // done
375         OnapPDPGroup group = null;
376         try {
377             group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
378         } catch (PAPException e) {
379             LOGGER.error("Exception occured While PUT operation is performing for PDP Group" + " -  RequestId - "
380                     + requestId + e);
381         }
382         if (group == null) {
383             String message = "Unknown groupId '" + groupId + "'.";
384             LOGGER.error(MessageCodes.ERROR_DATA_ISSUE + " - RequestId -  " + requestId + " - " + message);
385             loggingContext.transactionEnded();
386             PolicyLogger.audit("Transaction Failed - See Error.log");
387             response.addHeader(ERROR, "UnknownGroup");
388             response.addHeader(MESSAGE, message);
389             response.setStatus(HttpServletResponse.SC_NOT_FOUND);
390             return;
391         }
392         loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
393         RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
394         removePolicy.prepareToRemove();
395         List<String> policyIdList = Arrays.asList(polName.split(","));
396         for (String policyName : policyIdList) {
397             if (!policyName.endsWith("xml")) {
398                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
399                         + "policyName must be the full name of the file to be deleted including version and extension";
400                 LOGGER.error(message + "   - RequestId - " + requestId);
401                 response.addHeader(ERROR, message);
402                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
403                 return;
404             }
405             PDPPolicy policy = group.getPolicy(policyName);
406             if (policy == null) {
407                 String message =
408                         XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP - " + policyName;
409                 LOGGER.error(message + " - RequestId   - " + requestId);
410                 response.addHeader(ERROR, message);
411                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
412                 return;
413             }
414             if (StringUtils.indexOfAny(policy.getId(), "Config_MS_", "BRMS_Param") >= 0) {
415                 preSafetyCheck(policy);
416             }
417             LOGGER.info("Preparing to remove policy from group: " + group.getId() + "- RequestId - " + requestId);
418             removePolicy.removePolicy(policy);
419         }
420         OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
421         String userId = request.getParameter("userId");
422         String responseString = deletePolicyFromPdpGroup(updatedGroup, loggingContext, userId);
423
424         switch (responseString) {
425             case SUCCESS:
426                 loggingContext.transactionEnded();
427                 LOGGER.info("Policy successfully removed from PDP - " + polName + " -   RequestId - " + requestId);
428                 PolicyLogger.audit("Policy successfully deleted!");
429                 response.setStatus(HttpServletResponse.SC_OK);
430                 response.addHeader("successMapKey", SUCCESS);
431                 response.addHeader(OPERATION, DELETE);
432                 break;
433             case "No Group":
434                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
435                 LOGGER.error(message + " - RequestId - " + requestId);
436                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
437                 response.addHeader(ERROR, "groupUpdate");
438                 response.addHeader(MESSAGE, message);
439                 break;
440             case "DB Error":
441                 LOGGER.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database"
442                         + " - RequestId - " + requestId);
443                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
444                 response.addHeader(ERROR, "deleteDB");
445                 break;
446             default:
447                 LOGGER.error(MessageCodes.ERROR_UNKNOWN
448                         + " Failed to delete the policy for an unknown reason.  Check the file system and other logs "
449                         + "for " + "further information.");
450                 response.addHeader(ERROR, UNKNOWN);
451                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
452                 break;
453         }
454     }
455
456     private String deletePolicyFromPdpGroup(OnapPDPGroup group, OnapLoggingContext loggingContext, String userId) {
457         PolicyDbDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
458         String response = null;
459         loggingContext.setServiceName("API:PAP.DeleteHandler");
460         OnapPDPGroup existingGroup = null;
461         try {
462             existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
463         } catch (PAPException e1) {
464             PolicyLogger.error("Exception occured While Deleting Policy From PDP Group" + e1);
465         }
466         if (!(group instanceof StdPDPGroup) || existingGroup == null
467                 || !(group.getId().equals(existingGroup.getId()))) {
468             String existingId = null;
469             if (existingGroup != null) {
470                 existingId = existingGroup.getId();
471             }
472             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingId
473                     + " objectFromJSON=" + group);
474             loggingContext.transactionEnded();
475             PolicyLogger.audit("Transaction Failed - See Error.log");
476             response = "No Group";
477             return response;
478         }
479         // The Path on the PAP side is not carried on the RESTful interface with the AC
480         // (because it is local to the PAP)
481         // so we need to fill that in before submitting the group for update
482         ((StdPDPGroup) group).setDirectory(((StdPDPGroup) existingGroup).getDirectory());
483         try {
484             acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete", userId);
485         } catch (Exception e) {
486             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
487                     " Error while updating group in the database: " + "group=" + existingGroup.getId());
488             response = "DB Error";
489             return response;
490         }
491         try {
492             XACMLPapServlet.getPAPEngine().updateGroup(group);
493         } catch (PAPException e) {
494             PolicyLogger.error("Exception occured While Updating PDP Groups" + e);
495             response = "error in updateGroup method";
496         }
497         PolicyLogger.debug("Group '" + group.getId() + "' updated");
498         acPutTransaction.commitTransaction();
499         // Group changed, which might include changing the policies
500         try {
501             newgroup = existingGroup;
502         } catch (Exception e) {
503             PolicyLogger.error("Exception occured in Group Change Method" + e);
504             response = "error in groupChanged method";
505         }
506         if (response == null) {
507             response = SUCCESS;
508             loggingContext.transactionEnded();
509             PolicyLogger.audit("Policy successfully deleted!");
510         }
511         loggingContext.transactionEnded();
512         PolicyLogger.audit("Transaction Ended");
513         return response;
514     }
515
516     public OnapPDPGroup getDeletedGroup() {
517         return newgroup;
518     }
519
520     public boolean preSafetyCheck(PDPPolicy policy) {
521         return true;
522     }
523
524     /**
525      * Gets the single instance of DeleteHandler.
526      *
527      * @return single instance of DeleteHandler
528      */
529     public static DeleteHandler getInstance() {
530         try {
531             Class<?> deleteHandler = Class
532                     .forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
533             return (DeleteHandler) deleteHandler.newInstance();
534         } catch (Exception e) {
535             LOGGER.error(e.getMessage(), e);
536         }
537         return null;
538     }
539
540 }