2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 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=========================================================
20 package org.onap.policy.pap.xacml.rest.handler;
23 import java.io.IOException;
24 import java.sql.Connection;
25 import java.sql.DriverManager;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.sql.Statement;
29 import java.util.List;
31 import javax.persistence.EntityManager;
32 import javax.persistence.Query;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
36 import org.onap.policy.common.logging.ONAPLoggingContext;
37 import org.onap.policy.common.logging.eelf.MessageCodes;
38 import org.onap.policy.common.logging.eelf.PolicyLogger;
39 import org.onap.policy.common.logging.flexlogger.FlexLogger;
40 import org.onap.policy.common.logging.flexlogger.Logger;
41 import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
42 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
43 import org.onap.policy.pap.xacml.rest.elk.client.PolicyElasticSearchController;
44 import org.onap.policy.pap.xacml.rest.model.RemoveGroupPolicy;
45 import org.onap.policy.pap.xacml.rest.util.JPAUtils;
46 import org.onap.policy.rest.XACMLRestProperties;
47 import org.onap.policy.rest.adapter.PolicyRestAdapter;
48 import org.onap.policy.rest.jpa.PolicyEntity;
49 import org.onap.policy.rest.jpa.PolicyVersion;
50 import org.onap.policy.utils.PolicyUtils;
51 import org.onap.policy.xacml.api.XACMLErrorConstants;
52 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
53 import org.onap.policy.xacml.std.pap.StdPAPPolicy;
54 import org.onap.policy.xacml.std.pap.StdPDPGroup;
56 import com.att.research.xacml.api.pap.PAPException;
57 import com.att.research.xacml.api.pap.PDPPolicy;
58 import com.att.research.xacml.util.XACMLProperties;
60 public class DeleteHandler {
62 private OnapPDPGroup newgroup;
63 private static Logger logger = FlexLogger.getLogger(DeleteHandler.class);
64 public static final String POLICY_IN_PDP = "PolicyInPDP";
65 public static final String ERROR = "error";
66 public static final String UNKNOWN = "unknown";
67 private static final String REGEX = "[0-9a-zA-Z._]*";
69 public void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response)
70 throws IOException, SQLException {
71 // get the request content into a String
73 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
74 scanner.useDelimiter("\\A");
75 json = scanner.hasNext() ? scanner.next() : "";
77 PolicyLogger.info("JSON request from API to Delete Policy from the PAP: " + json);
78 // convert Object sent as JSON into local object
79 StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
80 String policyName = policy.getPolicyName();
81 boolean policyVersionDeleted = false;
82 String removeXMLExtension;
84 String removeVersionExtension;
85 String splitPolicyName = null;
86 String[] split = null;
87 String status = ERROR;
88 PolicyEntity policyEntity = null;
89 JPAUtils jpaUtils = null;
91 String papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
92 String papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
93 String papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
94 String papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
95 Connection con = null;
98 jpaUtils = JPAUtils.getJPAUtilsInstance(XACMLPapServlet.getEmf());
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);
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);
114 EntityManager em = XACMLPapServlet.getEmf().createEntityManager();
115 Query policyEntityQuery = null;
117 if (policyName.endsWith(".xml")) {
118 removeXMLExtension = policyName.replace(".xml", "");
120 Integer.parseInt(removeXMLExtension.substring(removeXMLExtension.lastIndexOf('.') + 1));
121 removeVersionExtension = removeXMLExtension.substring(0, removeXMLExtension.lastIndexOf('.'));
122 boolean queryCheck = true;
123 if (policy.getDeleteCondition().equalsIgnoreCase("All Versions")) {
124 if (policyName.contains("Config_")) {
125 splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
126 } else if (policyName.contains("Action_")) {
127 splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
128 } else if (policyName.contains("Decision_")) {
129 splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
131 if (splitPolicyName != null) {
132 split = splitPolicyName.split(":");
134 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN +
135 "Failed to delete the policy. Please, provide the valid policyname.");
136 response.addHeader(ERROR, UNKNOWN);
137 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
140 policyEntityQuery = em.createQuery(
141 "SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope");
142 } else if (policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
143 if (policyName.contains("Config_")) {
144 splitPolicyName = policyName.replace(".Config_", ":Config_");
145 } else if (policyName.contains("Action_")) {
146 splitPolicyName = policyName.replace(".Action_", ":Action_");
147 } else if (policyName.contains("Decision_")) {
148 splitPolicyName = policyName.replace(".Decision_", ":Decision_");
150 split = splitPolicyName.split(":");
152 policyEntityQuery = em.createQuery(
153 "SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope");
157 policyEntityQuery.setParameter("pName", "%" + split[1] + "%");
159 policyEntityQuery.setParameter("pName", split[1]);
162 policyEntityQuery.setParameter("pScope", split[0]);
163 List<?> peResult = policyEntityQuery.getResultList();
164 if (!peResult.isEmpty()) {
165 Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
166 getPolicyVersion.setParameter("pname", removeVersionExtension.replace(".", File.separator));
167 List<?> pvResult = getPolicyVersion.getResultList();
168 PolicyVersion pVersion = (PolicyVersion) pvResult.get(0);
170 em.getTransaction().begin();
171 Class.forName(papDbDriver);
172 con = DriverManager.getConnection(papDbUrl, papDbUser, papDbPassword);
174 if (policy.getDeleteCondition().equalsIgnoreCase("All Versions")) {
175 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
177 for (Object peData : peResult) {
178 policyEntity = (PolicyEntity) peData;
179 status = deletePolicyEntityData(em, policyEntity);
182 status = POLICY_IN_PDP;
186 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE +
187 "Exception Occured while deleting the Entity from Database.");
188 response.addHeader(ERROR, UNKNOWN);
189 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
192 PolicyLogger.error(MessageCodes.GENERAL_WARNING +
193 "Policy can't be deleted, it is active in PDP Groups.");
194 response.addHeader(ERROR, POLICY_IN_PDP);
195 response.setStatus(HttpServletResponse.SC_CONFLICT);
199 policyVersionDeleted = true;
201 } catch (Exception e) {
202 logger.error(e.getMessage(), e);
203 policyVersionDeleted = false;
207 } else if (policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
208 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
210 policyEntity = (PolicyEntity) peResult.get(0);
211 status = deletePolicyEntityData(em, policyEntity);
213 status = POLICY_IN_PDP;
216 if (ERROR.equals(status)) {
217 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE +
218 "Exception Occured while deleting the Entity from Database.");
219 response.addHeader(ERROR, UNKNOWN);
220 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
222 } else if (POLICY_IN_PDP.equals(status)) {
223 PolicyLogger.error(MessageCodes.GENERAL_WARNING +
224 "Policy can't be deleted, it is active in PDP Groups.");
225 response.addHeader(ERROR, POLICY_IN_PDP);
226 response.setStatus(HttpServletResponse.SC_CONFLICT);
229 if (currentVersion > 1) {
230 if (!peResult.isEmpty()) {
231 for (Object object : peResult) {
232 policyEntity = (PolicyEntity) object;
233 String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
234 int policyEntityVersion = Integer.parseInt(
235 policyEntityName.substring(policyEntityName.lastIndexOf('.') + 1));
236 if (policyEntityVersion > newVersion) {
237 newVersion = policyEntityVersion - 1;
241 pVersion.setActiveVersion(newVersion);
242 pVersion.setHigherVersion(newVersion);
244 policyVersionDeleted = true;
245 em.persist(pVersion);
246 } catch (Exception e) {
247 logger.error(e.getMessage(), e);
248 policyVersionDeleted = false;
252 policyVersionDeleted = true;
254 } catch (Exception e) {
255 logger.error(e.getMessage(), e);
256 policyVersionDeleted = false;
262 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN +
263 "Failed to delete the policy for an unknown reason. Check the file system and other logs" +
264 " for further information.");
265 response.addHeader(ERROR, UNKNOWN);
266 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
270 em.getTransaction().commit();
271 } catch (Exception e) {
272 em.getTransaction().rollback();
273 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
274 response.addHeader(ERROR, "deleteDB");
275 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
284 if (policyVersionDeleted) {
285 response.setStatus(HttpServletResponse.SC_OK);
286 response.addHeader("successMapKey", "success");
287 response.addHeader("operation", "delete");
289 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN +
290 "Failed to delete the policy for an unknown reason. Check the file system and other logs for " +
291 "further information.");
292 response.addHeader(ERROR, UNKNOWN);
293 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
297 public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity) {
298 PolicyElasticSearchController controller = new PolicyElasticSearchController();
299 PolicyRestAdapter policyData = new PolicyRestAdapter();
300 String policyName = policyEntity.getPolicyName();
302 if (policyName.contains("Config_")) {
303 em.remove(policyEntity.getConfigurationData());
304 } else if (policyName.contains("Action_")) {
305 em.remove(policyEntity.getActionBodyEntity());
307 String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
308 policyData.setNewFileName(searchPolicyName);
309 controller.deleteElk(policyData);
310 em.remove(policyEntity);
311 } catch (Exception e) {
312 logger.error(e.getMessage(), e);
318 public static boolean checkPolicyGroupEntity(Connection con, List<?> peResult) throws SQLException {
319 for (Object peData : peResult) {
320 PolicyEntity policyEntity = (PolicyEntity) peData;
321 try (Statement st = con.createStatement();
322 ResultSet rs = st.executeQuery(
323 "Select * from PolicyGroupEntity where policyid = '" + policyEntity.getPolicyId() + "'")) {
324 boolean gEntityList = rs.next();
333 public void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response,
334 ONAPLoggingContext loggingContext) throws IOException {
336 String policyName = request.getParameter("policyName");
337 String groupId = request.getParameter("groupId");
338 String responseString = null;
340 if (groupId != null && !groupId.matches(REGEX)) {
341 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
342 response.addHeader("error", ERROR);
343 response.addHeader("message", "Group Id is not valid");
347 PolicyLogger.info("JSON request from API to Delete Policy from the PDP: " + policyName);
349 // for PUT operations the group may or may not need to exist before the operation can be done
350 OnapPDPGroup group = null;
352 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
353 } catch (PAPException e) {
354 PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group" + e);
357 String message = "Unknown groupId '" + groupId + "'.";
358 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
359 loggingContext.transactionEnded();
360 PolicyLogger.audit("Transaction Failed - See Error.log");
361 response.addHeader(ERROR, "UnknownGroup");
362 response.addHeader("message", message);
363 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
366 loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
367 if (policyName.contains("xml")) {
369 .debug("The full file name including the extension was provided for policyName.. continue.");
371 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
372 + "policyName must be the full name of the file to be deleted including version and extension";
373 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
374 + "policyName must be the full name of the file to be deleted including version and extension");
375 response.addHeader(ERROR, message);
376 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
379 RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
380 PDPPolicy policy = group.getPolicy(policyName);
381 if (policy != null) {
383 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
384 if (preSafetyCheck(policy)) {
385 PolicyLogger.debug("Precheck Successful.");
388 PolicyLogger.info("Preparing to remove policy from group: " + group.getId());
389 removePolicy.prepareToRemove(policy);
390 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
391 responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
393 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
394 PolicyLogger.error(message);
395 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
396 response.addHeader(ERROR, message);
397 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
401 switch (responseString) {
403 loggingContext.transactionEnded();
404 PolicyLogger.info("Policy successfully deleted!");
405 PolicyLogger.audit("Policy successfully deleted!");
406 response.setStatus(HttpServletResponse.SC_OK);
407 response.addHeader("successMapKey", "success");
408 response.addHeader("operation", "delete");
411 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
412 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
413 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
414 response.addHeader(ERROR, "groupUpdate");
415 response.addHeader("message", message);
418 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
419 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
420 response.addHeader(ERROR, "deleteDB");
423 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN +
424 " Failed to delete the policy for an unknown reason. Check the file system and other logs " +
426 "further information.");
427 response.addHeader(ERROR, UNKNOWN);
428 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
433 private String deletePolicyFromPDPGroup(OnapPDPGroup group, ONAPLoggingContext loggingContext) {
434 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
435 String response = null;
436 loggingContext.setServiceName("API:PAP.DeleteHandler");
437 OnapPDPGroup existingGroup = null;
439 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
440 } catch (PAPException e1) {
441 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group" + e1);
443 if (!(group instanceof StdPDPGroup) || existingGroup == null ||
444 !(group.getId().equals(existingGroup.getId()))) {
445 String existingID = null;
446 if (existingGroup != null) {
447 existingID = existingGroup.getId();
449 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingID +
450 " objectFromJSON=" + group);
451 loggingContext.transactionEnded();
452 PolicyLogger.audit("Transaction Failed - See Error.log");
453 response = "No Group";
456 // The Path on the PAP side is not carried on the RESTful interface with the AC
457 // (because it is local to the PAP)
458 // so we need to fill that in before submitting the group for update
459 ((StdPDPGroup) group).setDirectory(((StdPDPGroup) existingGroup).getDirectory());
461 acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete");
462 } catch (Exception e) {
463 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet",
464 " Error while updating group in the database: "
465 + "group=" + existingGroup.getId());
466 response = "DB Error";
470 XACMLPapServlet.getPAPEngine().updateGroup(group);
471 } catch (PAPException e) {
472 PolicyLogger.error("Exception occured While Updating PDP Groups" + e);
473 response = "error in updateGroup method";
475 PolicyLogger.debug("Group '" + group.getId() + "' updated");
476 acPutTransaction.commitTransaction();
477 // Group changed, which might include changing the policies
479 newgroup = existingGroup;
480 } catch (Exception e) {
481 PolicyLogger.error("Exception occured in Group Change Method" + e);
482 response = "error in groupChanged method";
484 if (response == null) {
485 response = "success";
486 loggingContext.transactionEnded();
487 PolicyLogger.audit("Policy successfully deleted!");
489 loggingContext.transactionEnded();
490 PolicyLogger.audit("Transaction Ended");
494 public OnapPDPGroup getDeletedGroup() {
498 public boolean preSafetyCheck(PDPPolicy policy) {
502 public static DeleteHandler getInstance() {
504 Class<?> deleteHandler = Class.forName(
505 XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
506 return (DeleteHandler) deleteHandler.newInstance();
507 } catch (Exception e) {
508 logger.error(e.getMessage(), e);