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 {
356 String groupId = request.getParameter("groupId");
358 if (groupId != null && !groupId.matches(REGEX)) {
359 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
360 response.addHeader(ERROR, ERROR);
361 response.addHeader(MESSAGE, "Group Id is not valid");
364 String requestId = request.getHeader("X-ECOMP-RequestID");
365 String polName = request.getParameter("policyName");
366 LOGGER.info("JSON request from API to Delete Policy from the PDP - " + polName + " -RequestId - " + requestId);
368 // for PUT operations the group may or may not need to exist before the operation can be
370 OnapPDPGroup group = null;
372 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
373 } catch (PAPException e) {
374 LOGGER.error("Exception occured While PUT operation is performing for PDP Group" + " - RequestId - "
378 String message = "Unknown groupId '" + groupId + "'.";
379 LOGGER.error(MessageCodes.ERROR_DATA_ISSUE + " - RequestId - " + requestId + " - " + message);
380 loggingContext.transactionEnded();
381 PolicyLogger.audit("Transaction Failed - See Error.log");
382 response.addHeader(ERROR, "UnknownGroup");
383 response.addHeader(MESSAGE, message);
384 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
387 loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
388 RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
389 removePolicy.prepareToRemove();
390 List<String> policyIdList = Arrays.asList(polName.split(","));
391 for (String policyName : policyIdList) {
392 if (!policyName.endsWith("xml")) {
393 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
394 + "policyName must be the full name of the file to be deleted including version and extension";
395 LOGGER.error(message + " - RequestId - " + requestId);
396 response.addHeader(ERROR, message);
397 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
400 PDPPolicy policy = group.getPolicy(policyName);
401 if (policy == null) {
403 XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP - " + policyName;
404 LOGGER.error(message + " - RequestId - " + requestId);
405 response.addHeader(ERROR, message);
406 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
409 if (StringUtils.indexOfAny(policy.getId(), "Config_MS_", "BRMS_Param") >= 0) {
410 preSafetyCheck(policy);
412 LOGGER.info("Preparing to remove policy from group: " + group.getId() + "- RequestId - " + requestId);
413 removePolicy.removePolicy(policy);
415 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
416 String userId = request.getParameter("userId");
417 String responseString = deletePolicyFromPdpGroup(updatedGroup, loggingContext, userId);
419 switch (responseString) {
421 loggingContext.transactionEnded();
422 LOGGER.info("Policy successfully removed from PDP - " + polName + " - RequestId - " + requestId);
423 PolicyLogger.audit("Policy successfully deleted!");
424 response.setStatus(HttpServletResponse.SC_OK);
425 response.addHeader("successMapKey", SUCCESS);
426 response.addHeader(OPERATION, DELETE);
429 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
430 LOGGER.error(message + " - RequestId - " + requestId);
431 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
432 response.addHeader(ERROR, "groupUpdate");
433 response.addHeader(MESSAGE, message);
436 LOGGER.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database"
437 + " - RequestId - " + requestId);
438 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
439 response.addHeader(ERROR, "deleteDB");
442 LOGGER.error(MessageCodes.ERROR_UNKNOWN
443 + " Failed to delete the policy for an unknown reason. Check the file system and other logs "
444 + "for " + "further information.");
445 response.addHeader(ERROR, UNKNOWN);
446 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
451 private String deletePolicyFromPdpGroup(OnapPDPGroup group, ONAPLoggingContext loggingContext, String userId) {
452 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
453 String response = null;
454 loggingContext.setServiceName("API:PAP.DeleteHandler");
455 OnapPDPGroup existingGroup = null;
457 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
458 } catch (PAPException e1) {
459 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group" + e1);
461 if (!(group instanceof StdPDPGroup) || existingGroup == null
462 || !(group.getId().equals(existingGroup.getId()))) {
463 String existingId = null;
464 if (existingGroup != null) {
465 existingId = existingGroup.getId();
467 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingId
468 + " objectFromJSON=" + group);
469 loggingContext.transactionEnded();
470 PolicyLogger.audit("Transaction Failed - See Error.log");
471 response = "No Group";
474 // The Path on the PAP side is not carried on the RESTful interface with the AC
475 // (because it is local to the PAP)
476 // so we need to fill that in before submitting the group for update
477 ((StdPDPGroup) group).setDirectory(((StdPDPGroup) existingGroup).getDirectory());
479 acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete", userId);
480 } catch (Exception e) {
481 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
482 " Error while updating group in the database: " + "group=" + existingGroup.getId());
483 response = "DB Error";
487 XACMLPapServlet.getPAPEngine().updateGroup(group);
488 } catch (PAPException e) {
489 PolicyLogger.error("Exception occured While Updating PDP Groups" + e);
490 response = "error in updateGroup method";
492 PolicyLogger.debug("Group '" + group.getId() + "' updated");
493 acPutTransaction.commitTransaction();
494 // Group changed, which might include changing the policies
496 newgroup = existingGroup;
497 } catch (Exception e) {
498 PolicyLogger.error("Exception occured in Group Change Method" + e);
499 response = "error in groupChanged method";
501 if (response == null) {
503 loggingContext.transactionEnded();
504 PolicyLogger.audit("Policy successfully deleted!");
506 loggingContext.transactionEnded();
507 PolicyLogger.audit("Transaction Ended");
511 public OnapPDPGroup getDeletedGroup() {
515 public boolean preSafetyCheck(PDPPolicy policy) {
520 * Gets the single instance of DeleteHandler.
522 * @return single instance of DeleteHandler
524 public static DeleteHandler getInstance() {
526 Class<?> deleteHandler = Class
527 .forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
528 return (DeleteHandler) deleteHandler.newInstance();
529 } catch (Exception e) {
530 LOGGER.error(e.getMessage(), e);