2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.pap.xacml.rest.handler;
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.api.pap.PDPPolicy;
26 import com.att.research.xacml.util.XACMLProperties;
29 import java.io.IOException;
30 import java.util.Arrays;
31 import java.util.List;
33 import javax.script.SimpleBindings;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
37 import org.apache.commons.lang3.StringUtils;
38 import org.onap.policy.common.logging.OnapLoggingContext;
39 import org.onap.policy.common.logging.eelf.MessageCodes;
40 import org.onap.policy.common.logging.eelf.PolicyLogger;
41 import org.onap.policy.common.logging.flexlogger.FlexLogger;
42 import org.onap.policy.common.logging.flexlogger.Logger;
43 import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
44 import org.onap.policy.pap.xacml.rest.components.PolicyDbDaoTransaction;
45 import org.onap.policy.pap.xacml.rest.elk.client.PolicyElasticSearchController;
46 import org.onap.policy.pap.xacml.rest.model.RemoveGroupPolicy;
47 import org.onap.policy.pap.xacml.rest.util.JPAUtils;
48 import org.onap.policy.rest.adapter.PolicyRestAdapter;
49 import org.onap.policy.rest.dao.CommonClassDao;
50 import org.onap.policy.rest.jpa.PolicyEntity;
51 import org.onap.policy.rest.jpa.PolicyVersion;
52 import org.onap.policy.utils.PolicyUtils;
53 import org.onap.policy.xacml.api.XACMLErrorConstants;
54 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
55 import org.onap.policy.xacml.std.pap.StdPAPPolicy;
56 import org.onap.policy.xacml.std.pap.StdPDPGroup;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.stereotype.Component;
61 public class DeleteHandler {
63 private static CommonClassDao commonClassDao;
66 public DeleteHandler(CommonClassDao commonClassDao) {
67 DeleteHandler.commonClassDao = commonClassDao;
70 public DeleteHandler() {
71 // Default Constructor
74 private OnapPDPGroup newgroup;
75 private static final Logger LOGGER = FlexLogger.getLogger(DeleteHandler.class);
76 private static final String POLICY_IN_PDP = "PolicyInPDP";
77 private static final String ERROR = "error";
78 private static final String MESSAGE = "message";
79 private static final String UNKNOWN = "unknown";
80 private static final String SUCCESS = "success";
81 private static final String OPERATION = "operation";
82 private static final String CONFIG = "Config_";
83 private static final String REGEX = "[0-9a-zA-Z._]*";
84 private static final String DELETE = "delete";
85 private static final String ACTION = "Action_";
88 * Do API delete from PAP.
90 * @param request the request
91 * @param response the response
92 * @throws IOException Signals that an I/O exception has occurred.
94 public void doApiDeleteFromPap(HttpServletRequest request, HttpServletResponse response) throws IOException {
95 // get the request content into a String
97 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
98 scanner.useDelimiter("\\A");
99 json = scanner.hasNext() ? scanner.next() : "";
101 PolicyLogger.info("JSON request from API to Delete Policy from the PAP: " + json);
102 // convert Object sent as JSON into local object
103 StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
104 String policyName = policy.getPolicyName();
105 boolean policyVersionDeleted = false;
106 String removeXmlExtension;
108 String removeVersionExtension;
109 String splitPolicyName = null;
110 String[] split = null;
111 String status = ERROR;
112 PolicyEntity policyEntity = null;
113 JPAUtils jpaUtils = null;
116 jpaUtils = JPAUtils.getJPAUtilsInstance();
117 } catch (Exception e) {
118 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "doAPIDeleteFromPAP",
119 " Could not create JPAUtils instance on the PAP");
120 response.addHeader(ERROR, "jpautils");
121 response.addHeader(OPERATION, DELETE);
122 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
125 if (jpaUtils.dbLockdownIgnoreErrors()) {
126 PolicyLogger.warn("Policies are locked down");
127 response.addHeader(OPERATION, DELETE);
128 response.addHeader("lockdown", "true");
129 response.setStatus(HttpServletResponse.SC_ACCEPTED);
132 String policyEntityQuery = null;
134 if (policyName.endsWith(".xml")) {
135 removeXmlExtension = policyName.replace(".xml", "");
137 Integer.parseInt(removeXmlExtension.substring(removeXmlExtension.lastIndexOf('.') + 1));
138 removeVersionExtension = removeXmlExtension.substring(0, removeXmlExtension.lastIndexOf('.'));
139 boolean queryCheck = true;
140 if ("All Versions".equalsIgnoreCase(policy.getDeleteCondition())) {
141 if (policyName.contains(CONFIG)) {
142 splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
143 } else if (policyName.contains(ACTION)) {
144 splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
145 } else if (policyName.contains("Decision_")) {
146 splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
148 if (splitPolicyName != null) {
149 split = splitPolicyName.split(":");
151 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
152 + "Failed to delete the policy. Please, provide the valid policyname.");
153 response.addHeader(ERROR, UNKNOWN);
154 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
158 "SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope";
159 } else if ("Current Version".equalsIgnoreCase(policy.getDeleteCondition())) {
160 if (policyName.contains(CONFIG)) {
161 splitPolicyName = policyName.replace(".Config_", ":Config_");
162 } else if (policyName.contains(ACTION)) {
163 splitPolicyName = policyName.replace(".Action_", ":Action_");
164 } else if (policyName.contains("Decision_")) {
165 splitPolicyName = policyName.replace(".Decision_", ":Decision_");
167 split = splitPolicyName.split(":");
169 policyEntityQuery = "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope";
171 SimpleBindings params = new SimpleBindings();
173 params.put("pName", "%" + split[1] + "%");
175 params.put("pName", split[1]);
178 params.put("pScope", split[0]);
179 List<?> peResult = commonClassDao.getDataByQuery(policyEntityQuery, params);
180 if (!peResult.isEmpty()) {
181 String getPolicyVersion = "Select p from PolicyVersion p where p.policyName=:pname";
182 SimpleBindings pvParams = new SimpleBindings();
183 pvParams.put("pname", removeVersionExtension.replace(".", File.separator));
184 List<?> pvResult = commonClassDao.getDataByQuery(getPolicyVersion, pvParams);
185 PolicyVersion polVersion = (PolicyVersion) pvResult.get(0);
187 if ("All Versions".equalsIgnoreCase(policy.getDeleteCondition())) {
188 boolean groupCheck = checkPolicyGroupEntity(peResult);
190 for (Object peData : peResult) {
191 policyEntity = (PolicyEntity) peData;
192 status = deletePolicyEntityData(policyEntity);
195 status = POLICY_IN_PDP;
199 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
200 + "Exception Occured while deleting the Entity from Database.");
201 response.addHeader(ERROR, UNKNOWN);
202 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
205 PolicyLogger.error(MessageCodes.GENERAL_WARNING
206 + "Policy can't be deleted, it is active in PDP Groups.");
207 response.addHeader(ERROR, POLICY_IN_PDP);
208 response.setStatus(HttpServletResponse.SC_CONFLICT);
212 policyVersionDeleted = true;
213 commonClassDao.delete(polVersion);
214 } catch (Exception e) {
215 LOGGER.error(e.getMessage(), e);
216 policyVersionDeleted = false;
220 } else if ("Current Version".equalsIgnoreCase(policy.getDeleteCondition())) {
221 boolean groupCheck = checkPolicyGroupEntity(peResult);
223 policyEntity = (PolicyEntity) peResult.get(0);
224 status = deletePolicyEntityData(policyEntity);
226 status = POLICY_IN_PDP;
229 if (ERROR.equals(status)) {
230 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE
231 + "Exception Occured while deleting the Entity from Database.");
232 response.addHeader(ERROR, UNKNOWN);
233 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
235 } else if (POLICY_IN_PDP.equals(status)) {
236 PolicyLogger.error(MessageCodes.GENERAL_WARNING
237 + "Policy can't be deleted, it is active in PDP Groups.");
238 response.addHeader(ERROR, POLICY_IN_PDP);
239 response.setStatus(HttpServletResponse.SC_CONFLICT);
242 if (currentVersion > 1) {
243 if (!peResult.isEmpty()) {
244 for (Object object : peResult) {
245 policyEntity = (PolicyEntity) object;
246 String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
247 int policyEntityVersion = Integer.parseInt(
248 policyEntityName.substring(policyEntityName.lastIndexOf('.') + 1));
249 if (policyEntityVersion > newVersion) {
250 newVersion = policyEntityVersion - 1;
254 polVersion.setActiveVersion(newVersion);
255 polVersion.setHigherVersion(newVersion);
257 policyVersionDeleted = true;
258 commonClassDao.save(polVersion);
259 } catch (Exception e) {
260 LOGGER.error(e.getMessage(), e);
261 policyVersionDeleted = false;
265 policyVersionDeleted = true;
266 commonClassDao.delete(polVersion);
267 } catch (Exception e) {
268 LOGGER.error(e.getMessage(), e);
269 policyVersionDeleted = false;
275 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
276 + "Failed to delete the policy for an unknown reason. Check the file system and other logs"
277 + " for further information.");
278 response.addHeader(ERROR, UNKNOWN);
279 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
283 } catch (Exception e) {
284 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
285 response.addHeader(ERROR, "deleteDB");
286 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
290 if (policyVersionDeleted) {
291 response.setStatus(HttpServletResponse.SC_OK);
292 response.addHeader("successMapKey", SUCCESS);
293 response.addHeader(OPERATION, DELETE);
295 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN
296 + "Failed to delete the policy for an unknown reason. Check the file system and other logs for "
297 + "further information.");
298 response.addHeader(ERROR, UNKNOWN);
299 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
304 * Delete policy entity data.
306 * @param policyEntity the policy entity
309 public static String deletePolicyEntityData(PolicyEntity policyEntity) {
310 PolicyElasticSearchController controller = new PolicyElasticSearchController();
311 PolicyRestAdapter policyData = new PolicyRestAdapter();
312 String policyName = policyEntity.getPolicyName();
314 if (policyName.contains("CONFIG") || policyName.contains("Decision_MS_")) {
315 commonClassDao.delete(policyEntity.getConfigurationData());
316 } else if (policyName.contains(ACTION)) {
317 commonClassDao.delete(policyEntity.getActionBodyEntity());
319 String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
320 policyData.setNewFileName(searchPolicyName);
321 controller.deleteElk(policyData);
322 commonClassDao.delete(policyEntity);
323 } catch (Exception e) {
324 LOGGER.error(e.getMessage(), e);
331 * Check policy group entity.
333 * @param peResult the pe result
334 * @return true, if successful
336 public static boolean checkPolicyGroupEntity(List<?> peResult) {
337 String groupEntityquery = "from PolicyGroupEntity where policyid = :policyEntityId";
338 for (Object peData : peResult) {
339 PolicyEntity policyEntity = (PolicyEntity) peData;
340 SimpleBindings geParams = new SimpleBindings();
341 geParams.put("policyEntityId", policyEntity.getPolicyId());
342 List<Object> groupobject = commonClassDao.getDataByQuery(groupEntityquery, geParams);
343 if (!groupobject.isEmpty()) {
351 * Do API delete from PDP.
353 * @param request the request
354 * @param response the response
355 * @param loggingContext the logging context
356 * @throws IOException Signals that an I/O exception has occurred.
358 public void doApiDeleteFromPdp(HttpServletRequest request, HttpServletResponse response,
359 OnapLoggingContext loggingContext) throws IOException {
361 String groupId = request.getParameter("groupId");
363 if (groupId != null && !groupId.matches(REGEX)) {
364 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
365 response.addHeader(ERROR, ERROR);
366 response.addHeader(MESSAGE, "Group Id is not valid");
369 String requestId = request.getHeader("X-ECOMP-RequestID");
370 String polName = request.getParameter("policyName");
371 LOGGER.info("JSON request from API to Delete Policy from the PDP - " + polName + " -RequestId - " + requestId);
373 // for PUT operations the group may or may not need to exist before the operation can be
375 OnapPDPGroup group = null;
377 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
378 } catch (PAPException e) {
379 LOGGER.error("Exception occured While PUT operation is performing for PDP Group" + " - RequestId - "
383 String message = "Unknown groupId '" + groupId + "'.";
384 LOGGER.error(MessageCodes.ERROR_DATA_ISSUE + " - RequestId - " + requestId + " - " + message);
385 loggingContext.transactionEnded();
386 PolicyLogger.audit("Transaction Failed - See Error.log");
387 response.addHeader(ERROR, "UnknownGroup");
388 response.addHeader(MESSAGE, message);
389 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
392 loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
393 RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
394 removePolicy.prepareToRemove();
395 List<String> policyIdList = Arrays.asList(polName.split(","));
396 for (String policyName : policyIdList) {
397 if (!policyName.endsWith("xml")) {
398 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
399 + "policyName must be the full name of the file to be deleted including version and extension";
400 LOGGER.error(message + " - RequestId - " + requestId);
401 response.addHeader(ERROR, message);
402 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
405 PDPPolicy policy = group.getPolicy(policyName);
406 if (policy == null) {
408 XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP - " + policyName;
409 LOGGER.error(message + " - RequestId - " + requestId);
410 response.addHeader(ERROR, message);
411 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
414 if (StringUtils.indexOfAny(policy.getId(), "Config_MS_", "BRMS_Param") >= 0) {
415 preSafetyCheck(policy);
417 LOGGER.info("Preparing to remove policy from group: " + group.getId() + "- RequestId - " + requestId);
418 removePolicy.removePolicy(policy);
420 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
421 String userId = request.getParameter("userId");
422 String responseString = deletePolicyFromPdpGroup(updatedGroup, loggingContext, userId);
424 switch (responseString) {
426 loggingContext.transactionEnded();
427 LOGGER.info("Policy successfully removed from PDP - " + polName + " - RequestId - " + requestId);
428 PolicyLogger.audit("Policy successfully deleted!");
429 response.setStatus(HttpServletResponse.SC_OK);
430 response.addHeader("successMapKey", SUCCESS);
431 response.addHeader(OPERATION, DELETE);
434 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
435 LOGGER.error(message + " - RequestId - " + requestId);
436 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
437 response.addHeader(ERROR, "groupUpdate");
438 response.addHeader(MESSAGE, message);
441 LOGGER.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database"
442 + " - RequestId - " + requestId);
443 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
444 response.addHeader(ERROR, "deleteDB");
447 LOGGER.error(MessageCodes.ERROR_UNKNOWN
448 + " Failed to delete the policy for an unknown reason. Check the file system and other logs "
449 + "for " + "further information.");
450 response.addHeader(ERROR, UNKNOWN);
451 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
456 private String deletePolicyFromPdpGroup(OnapPDPGroup group, OnapLoggingContext loggingContext, String userId) {
457 PolicyDbDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
458 String response = null;
459 loggingContext.setServiceName("API:PAP.DeleteHandler");
460 OnapPDPGroup existingGroup = null;
462 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
463 } catch (PAPException e1) {
464 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group" + e1);
466 if (!(group instanceof StdPDPGroup) || existingGroup == null
467 || !(group.getId().equals(existingGroup.getId()))) {
468 String existingId = null;
469 if (existingGroup != null) {
470 existingId = existingGroup.getId();
472 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingId
473 + " objectFromJSON=" + group);
474 loggingContext.transactionEnded();
475 PolicyLogger.audit("Transaction Failed - See Error.log");
476 response = "No Group";
479 // The Path on the PAP side is not carried on the RESTful interface with the AC
480 // (because it is local to the PAP)
481 // so we need to fill that in before submitting the group for update
482 ((StdPDPGroup) group).setDirectory(((StdPDPGroup) existingGroup).getDirectory());
484 acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete", userId);
485 } catch (Exception e) {
486 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
487 " Error while updating group in the database: " + "group=" + existingGroup.getId());
488 response = "DB Error";
492 XACMLPapServlet.getPAPEngine().updateGroup(group);
493 } catch (PAPException e) {
494 PolicyLogger.error("Exception occured While Updating PDP Groups" + e);
495 response = "error in updateGroup method";
497 PolicyLogger.debug("Group '" + group.getId() + "' updated");
498 acPutTransaction.commitTransaction();
499 // Group changed, which might include changing the policies
501 newgroup = existingGroup;
502 } catch (Exception e) {
503 PolicyLogger.error("Exception occured in Group Change Method" + e);
504 response = "error in groupChanged method";
506 if (response == null) {
508 loggingContext.transactionEnded();
509 PolicyLogger.audit("Policy successfully deleted!");
511 loggingContext.transactionEnded();
512 PolicyLogger.audit("Transaction Ended");
516 public OnapPDPGroup getDeletedGroup() {
520 public boolean preSafetyCheck(PDPPolicy policy) {
525 * Gets the single instance of DeleteHandler.
527 * @return single instance of DeleteHandler
529 public static DeleteHandler getInstance() {
531 Class<?> deleteHandler = Class
532 .forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
533 return (DeleteHandler) deleteHandler.newInstance();
534 } catch (Exception e) {
535 LOGGER.error(e.getMessage(), e);