2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.pap.xacml.rest.handler;
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;
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;
57 public class DeleteHandler {
59 private static CommonClassDao commonClassDao;
62 public DeleteHandler(CommonClassDao commonClassDao) {
63 DeleteHandler.commonClassDao = commonClassDao;
66 public DeleteHandler() {
67 // Default Constructor
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_";
84 * Do API delete from PAP.
86 * @param request the request
87 * @param response the response
88 * @throws IOException Signals that an I/O exception has occurred.
90 public void doApiDeleteFromPap(HttpServletRequest request, HttpServletResponse response) throws IOException {
91 // get the request content into a String
93 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
94 scanner.useDelimiter("\\A");
95 json = scanner.hasNext() ? scanner.next() : "";
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;
104 String removeVersionExtension;
105 String splitPolicyName = null;
106 String[] split = null;
107 String status = ERROR;
108 PolicyEntity policyEntity = null;
109 JPAUtils jpaUtils = null;
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);
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);
128 String policyEntityQuery = null;
130 if (policyName.endsWith(".xml")) {
131 removeXmlExtension = policyName.replace(".xml", "");
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_");
144 if (splitPolicyName != null) {
145 split = splitPolicyName.split(":");
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);
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_");
163 split = splitPolicyName.split(":");
165 policyEntityQuery = "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope";
167 SimpleBindings params = new SimpleBindings();
169 params.put("pName", "%" + split[1] + "%");
171 params.put("pName", split[1]);
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);
183 if ("All Versions".equalsIgnoreCase(policy.getDeleteCondition())) {
184 boolean groupCheck = checkPolicyGroupEntity(peResult);
186 for (Object peData : peResult) {
187 policyEntity = (PolicyEntity) peData;
188 status = deletePolicyEntityData(policyEntity);
191 status = POLICY_IN_PDP;
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);
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);
208 policyVersionDeleted = true;
209 commonClassDao.delete(polVersion);
210 } catch (Exception e) {
211 LOGGER.error(e.getMessage(), e);
212 policyVersionDeleted = false;
216 } else if ("Current Version".equalsIgnoreCase(policy.getDeleteCondition())) {
217 boolean groupCheck = checkPolicyGroupEntity(peResult);
219 policyEntity = (PolicyEntity) peResult.get(0);
220 status = deletePolicyEntityData(policyEntity);
222 status = POLICY_IN_PDP;
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);
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);
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;
250 polVersion.setActiveVersion(newVersion);
251 polVersion.setHigherVersion(newVersion);
253 policyVersionDeleted = true;
254 commonClassDao.save(polVersion);
255 } catch (Exception e) {
256 LOGGER.error(e.getMessage(), e);
257 policyVersionDeleted = false;
261 policyVersionDeleted = true;
262 commonClassDao.delete(polVersion);
263 } catch (Exception e) {
264 LOGGER.error(e.getMessage(), e);
265 policyVersionDeleted = false;
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);
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);
286 if (policyVersionDeleted) {
287 response.setStatus(HttpServletResponse.SC_OK);
288 response.addHeader("successMapKey", SUCCESS);
289 response.addHeader(OPERATION, DELETE);
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);
300 * Delete policy entity data.
302 * @param policyEntity the policy entity
305 public static String deletePolicyEntityData(PolicyEntity policyEntity) {
306 PolicyElasticSearchController controller = new PolicyElasticSearchController();
307 PolicyRestAdapter policyData = new PolicyRestAdapter();
308 String policyName = policyEntity.getPolicyName();
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());
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);
327 * Check policy group entity.
329 * @param peResult the pe result
330 * @return true, if successful
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()) {
347 * Do API delete from PDP.
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.
354 public void doApiDeleteFromPdp(HttpServletRequest request, HttpServletResponse response,
355 ONAPLoggingContext loggingContext) throws IOException {
357 String groupId = request.getParameter("groupId");
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");
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);
369 // for PUT operations the group may or may not need to exist before the operation can be
371 OnapPDPGroup group = null;
373 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
374 } catch (PAPException e) {
375 LOGGER.error("Exception occured While PUT operation is performing for PDP Group" + " - RequestId - "
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);
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);
401 PDPPolicy policy = group.getPolicy(policyName);
402 if (policy == null) {
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);
410 if (StringUtils.indexOfAny(policy.getId(), "Config_MS_", "BRMS_Param") >= 0) {
411 preSafetyCheck(policy);
413 LOGGER.info("Preparing to remove policy from group: " + group.getId() + "- RequestId - " + requestId);
414 removePolicy.removePolicy(policy);
416 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
417 String userId = request.getParameter("userId");
418 String responseString = deletePolicyFromPdpGroup(updatedGroup, loggingContext, userId);
420 switch (responseString) {
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);
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);
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");
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);
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;
458 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
459 } catch (PAPException e1) {
460 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group" + e1);
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();
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";
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());
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";
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";
493 PolicyLogger.debug("Group '" + group.getId() + "' updated");
494 acPutTransaction.commitTransaction();
495 // Group changed, which might include changing the policies
497 newgroup = existingGroup;
498 } catch (Exception e) {
499 PolicyLogger.error("Exception occured in Group Change Method" + e);
500 response = "error in groupChanged method";
502 if (response == null) {
504 loggingContext.transactionEnded();
505 PolicyLogger.audit("Policy successfully deleted!");
507 loggingContext.transactionEnded();
508 PolicyLogger.audit("Transaction Ended");
512 public OnapPDPGroup getDeletedGroup() {
516 public boolean preSafetyCheck(PDPPolicy policy) {
521 * Gets the single instance of DeleteHandler.
523 * @return single instance of DeleteHandler
525 public static DeleteHandler getInstance() {
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);