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