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";
69 public void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response) throws IOException, SQLException {
70 // get the request content into a String
72 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
73 scanner.useDelimiter("\\A");
74 json = scanner.hasNext() ? scanner.next() : "";
76 PolicyLogger.info("JSON request from API to Delete Policy from the PAP: " + json);
77 // convert Object sent as JSON into local object
78 StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
79 String policyName = policy.getPolicyName();
80 Boolean policyVersionDeleted = false;
81 String removeXMLExtension;
83 String removeVersionExtension;
84 String splitPolicyName = null;
85 String[] split = null;
86 String status = ERROR;
87 PolicyEntity policyEntity = null;
88 JPAUtils jpaUtils = null;
90 String papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
91 String papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
92 String papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
93 String papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
94 Connection con = null;
97 jpaUtils = JPAUtils.getJPAUtilsInstance(XACMLPapServlet.getEmf());
98 } catch (Exception e) {
99 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP");
100 response.addHeader(ERROR, "jpautils");
101 response.addHeader("operation", "delete");
102 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
105 if (jpaUtils.dbLockdownIgnoreErrors()) {
106 PolicyLogger.warn("Policies are locked down");
107 response.addHeader("operation", "delete");
108 response.addHeader("lockdown", "true");
109 response.setStatus(HttpServletResponse.SC_ACCEPTED);
112 EntityManager em = XACMLPapServlet.getEmf().createEntityManager();
113 Query policyEntityQuery = null;
115 if(policyName.endsWith(".xml")){
116 removeXMLExtension = policyName.replace(".xml", "");
117 currentVersion = Integer.parseInt(removeXMLExtension.substring(removeXMLExtension.lastIndexOf('.')+1));
118 removeVersionExtension = removeXMLExtension.substring(0, removeXMLExtension.lastIndexOf('.'));
119 boolean queryCheck = true;
120 if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
121 if(policyName.contains("Config_")){
122 splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
123 }else if(policyName.contains("Action_")){
124 splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
125 }else if(policyName.contains("Decision_")){
126 splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
128 if(splitPolicyName != null){
129 split = splitPolicyName.split(":");
131 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy. Please, provide the valid policyname.");
132 response.addHeader(ERROR, UNKNOWN);
133 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
136 policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope");
137 }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
138 if(policyName.contains("Config_")){
139 splitPolicyName = policyName.replace(".Config_", ":Config_");
140 }else if(policyName.contains("Action_")){
141 splitPolicyName = policyName.replace(".Action_", ":Action_");
142 }else if(policyName.contains("Decision_")){
143 splitPolicyName = policyName.replace(".Decision_", ":Decision_");
145 split = splitPolicyName.split(":");
147 policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope");
151 policyEntityQuery.setParameter("pName", "%"+split[1]+"%");
153 policyEntityQuery.setParameter("pName", split[1]);
156 policyEntityQuery.setParameter("pScope", split[0]);
157 List<?> peResult = policyEntityQuery.getResultList();
158 if(!peResult.isEmpty()){
159 Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
160 getPolicyVersion.setParameter("pname", removeVersionExtension.replace(".", File.separator));
161 List<?> pvResult = getPolicyVersion.getResultList();
162 PolicyVersion pVersion = (PolicyVersion) pvResult.get(0);
164 em.getTransaction().begin();
165 Class.forName(papDbDriver);
166 con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
168 if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
169 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
171 for(Object peData : peResult){
172 policyEntity = (PolicyEntity) peData;
173 status = deletePolicyEntityData(em, policyEntity);
176 status = POLICY_IN_PDP;
178 if(status.equals(ERROR)){
179 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
180 response.addHeader(ERROR, UNKNOWN);
181 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
183 }else if(status.equals(POLICY_IN_PDP)){
184 PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
185 response.addHeader(ERROR, POLICY_IN_PDP);
186 response.setStatus(HttpServletResponse.SC_CONFLICT);
190 policyVersionDeleted = true;
193 logger.error(e.getMessage(),e);
194 policyVersionDeleted = false;
197 }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")){
198 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
200 policyEntity = (PolicyEntity) peResult.get(0);
201 status = deletePolicyEntityData(em, policyEntity);
203 status = POLICY_IN_PDP;
206 if(ERROR.equals(status)){
207 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
208 response.addHeader(ERROR, UNKNOWN);
209 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
211 }else if(POLICY_IN_PDP.equals(status)){
212 PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
213 response.addHeader(ERROR, POLICY_IN_PDP);
214 response.setStatus(HttpServletResponse.SC_CONFLICT);
217 if(currentVersion > 1){
218 if(!peResult.isEmpty()){
219 for(Object object : peResult){
220 policyEntity = (PolicyEntity) object;
221 String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
222 int policyEntityVersion = Integer.parseInt(policyEntityName.substring(policyEntityName.lastIndexOf('.')+1));
223 if(policyEntityVersion > newVersion){
224 newVersion = policyEntityVersion-1;
228 pVersion.setActiveVersion(newVersion);
229 pVersion.setHigherVersion(newVersion);
231 policyVersionDeleted = true;
232 em.persist(pVersion);
234 logger.error(e.getMessage(),e);
235 policyVersionDeleted = false;
239 policyVersionDeleted = true;
242 logger.error(e.getMessage(),e);
243 policyVersionDeleted = false;
249 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason. Check the file system and other logs for further information.");
250 response.addHeader(ERROR, UNKNOWN);
251 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
255 em.getTransaction().commit();
257 em.getTransaction().rollback();
258 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
259 response.addHeader(ERROR, "deleteDB");
260 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
269 if (policyVersionDeleted) {
270 response.setStatus(HttpServletResponse.SC_OK);
271 response.addHeader("successMapKey", "success");
272 response.addHeader("operation", "delete");
275 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason. Check the file system and other logs for further information.");
276 response.addHeader(ERROR, UNKNOWN);
277 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
282 public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity){
283 PolicyElasticSearchController controller = new PolicyElasticSearchController();
284 PolicyRestAdapter policyData = new PolicyRestAdapter();
285 String policyName = policyEntity.getPolicyName();
287 if(policyName.contains("Config_")){
288 em.remove(policyEntity.getConfigurationData());
289 }else if(policyName.contains("Action_")){
290 em.remove(policyEntity.getActionBodyEntity());
292 String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
293 policyData.setNewFileName(searchPolicyName);
294 controller.deleteElk(policyData);
295 em.remove(policyEntity);
297 logger.error(e.getMessage(),e);
303 public static boolean checkPolicyGroupEntity(Connection con, List<?> peResult) throws SQLException{
304 for(Object peData : peResult){
305 PolicyEntity policyEntity = (PolicyEntity) peData;
306 try(Statement st = con.createStatement();
307 ResultSet rs = st.executeQuery("Select * from PolicyGroupEntity where policyid = '"+policyEntity.getPolicyId()+"'")){
308 boolean gEntityList = rs.next();
317 public void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws IOException {
319 String policyName = request.getParameter("policyName");
320 String groupId = request.getParameter("groupId");
321 String responseString = null;
323 PolicyLogger.info("JSON request from API to Delete Policy from the PDP: " + policyName);
325 // for PUT operations the group may or may not need to exist before the operation can be done
326 OnapPDPGroup group = null;
328 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
329 } catch (PAPException e) {
330 PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group"+e);
333 String message = "Unknown groupId '" + groupId + "'.";
334 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
335 loggingContext.transactionEnded();
336 PolicyLogger.audit("Transaction Failed - See Error.log");
337 response.addHeader(ERROR, "UnknownGroup");
338 response.addHeader("message", message);
339 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
342 loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
343 if (policyName.contains("xml")) {
344 PolicyLogger.debug("The full file name including the extension was provided for policyName.. continue.");
346 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
347 + "policyName must be the full name of the file to be deleted including version and extension";
348 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
349 + "policyName must be the full name of the file to be deleted including version and extension");
350 response.addHeader(ERROR, message);
351 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
354 RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
355 PDPPolicy policy = group.getPolicy(policyName);
356 if (policy != null) {
358 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
359 if (preSafetyCheck(policy)) {
360 PolicyLogger.debug("Precheck Successful.");
363 PolicyLogger.info("Preparing to remove policy from group: " + group.getId());
364 removePolicy.prepareToRemove(policy);
365 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
366 responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
368 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
369 PolicyLogger.error(message);
370 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
371 response.addHeader(ERROR, message);
372 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
376 if (responseString.equals("success")) {
377 loggingContext.transactionEnded();
378 PolicyLogger.info("Policy successfully deleted!");
379 PolicyLogger.audit("Policy successfully deleted!");
380 response.setStatus(HttpServletResponse.SC_OK);
381 response.addHeader("successMapKey", "success");
382 response.addHeader("operation", "delete");
384 } else if (responseString.equals("No Group")) {
385 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
386 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
387 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
388 response.addHeader(ERROR, "groupUpdate");
389 response.addHeader("message", message);
391 } else if (responseString.equals("DB Error")) {
392 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
393 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
394 response.addHeader(ERROR, "deleteDB");
397 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " Failed to delete the policy for an unknown reason. Check the file system and other logs for further information.");
398 response.addHeader(ERROR, UNKNOWN);
399 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
404 private String deletePolicyFromPDPGroup (OnapPDPGroup group, ONAPLoggingContext loggingContext){
405 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
406 String response = null;
407 loggingContext.setServiceName("API:PAP.DeleteHandler");
408 OnapPDPGroup existingGroup = null;
410 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
411 } catch (PAPException e1) {
412 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group"+e1);
414 if (!(group instanceof StdPDPGroup) || existingGroup == null || !(group.getId().equals(existingGroup.getId()))) {
415 String existingID = null;
416 if(existingGroup != null){
417 existingID = existingGroup.getId();
419 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingID + " objectFromJSON="+group);
420 loggingContext.transactionEnded();
421 PolicyLogger.audit("Transaction Failed - See Error.log");
422 response = "No Group";
425 // The Path on the PAP side is not carried on the RESTful interface with the AC
426 // (because it is local to the PAP)
427 // so we need to fill that in before submitting the group for update
428 ((StdPDPGroup)group).setDirectory(((StdPDPGroup)existingGroup).getDirectory());
430 acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete");
431 } catch(Exception e){
432 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
433 +"group="+existingGroup.getId());
434 response = "DB Error";
438 XACMLPapServlet.getPAPEngine().updateGroup(group);
439 } catch (PAPException e) {
440 PolicyLogger.error("Exception occured While Updating PDP Groups"+e);
441 response = "error in updateGroup method";
443 PolicyLogger.debug("Group '" + group.getId() + "' updated");
444 acPutTransaction.commitTransaction();
445 // Group changed, which might include changing the policies
447 newgroup = existingGroup;
448 } catch (Exception e) {
449 PolicyLogger.error("Exception occured in Group Change Method"+e);
450 response = "error in groupChanged method";
453 response = "success";
454 loggingContext.transactionEnded();
455 PolicyLogger.audit("Policy successfully deleted!");
457 loggingContext.transactionEnded();
458 PolicyLogger.audit("Transaction Ended");
462 public OnapPDPGroup getDeletedGroup(){
466 public boolean preSafetyCheck(PDPPolicy policy) {
470 public static DeleteHandler getInstance() {
472 Class<?> deleteHandler = Class.forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
473 return (DeleteHandler) deleteHandler.newInstance();
474 } catch (Exception e) {
475 logger.error(e.getMessage(),e);