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