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