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) 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 if(groupId != null && !groupId.matches(REGEX) ){
324 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
325 response.addHeader("error",ERROR);
326 response.addHeader("message", "Group Id is not valid");
330 PolicyLogger.info("JSON request from API to Delete Policy from the PDP: " + policyName);
332 // for PUT operations the group may or may not need to exist before the operation can be done
333 OnapPDPGroup group = null;
335 group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
336 } catch (PAPException e) {
337 PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group"+e);
340 String message = "Unknown groupId '" + groupId + "'.";
341 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
342 loggingContext.transactionEnded();
343 PolicyLogger.audit("Transaction Failed - See Error.log");
344 response.addHeader(ERROR, "UnknownGroup");
345 response.addHeader("message", message);
346 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
349 loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
350 if (policyName.contains("xml")) {
351 PolicyLogger.debug("The full file name including the extension was provided for policyName.. continue.");
353 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
354 + "policyName must be the full name of the file to be deleted including version and extension";
355 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
356 + "policyName must be the full name of the file to be deleted including version and extension");
357 response.addHeader(ERROR, message);
358 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
361 RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
362 PDPPolicy policy = group.getPolicy(policyName);
363 if (policy != null) {
365 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
366 if (preSafetyCheck(policy)) {
367 PolicyLogger.debug("Precheck Successful.");
370 PolicyLogger.info("Preparing to remove policy from group: " + group.getId());
371 removePolicy.prepareToRemove(policy);
372 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
373 responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
375 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
376 PolicyLogger.error(message);
377 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
378 response.addHeader(ERROR, message);
379 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
383 if (responseString.equals("success")) {
384 loggingContext.transactionEnded();
385 PolicyLogger.info("Policy successfully deleted!");
386 PolicyLogger.audit("Policy successfully deleted!");
387 response.setStatus(HttpServletResponse.SC_OK);
388 response.addHeader("successMapKey", "success");
389 response.addHeader("operation", "delete");
391 } else if (responseString.equals("No Group")) {
392 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
393 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
394 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
395 response.addHeader(ERROR, "groupUpdate");
396 response.addHeader("message", message);
398 } else if (responseString.equals("DB Error")) {
399 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
400 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
401 response.addHeader(ERROR, "deleteDB");
404 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " Failed to delete the policy for an unknown reason. Check the file system and other logs for further information.");
405 response.addHeader(ERROR, UNKNOWN);
406 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
411 private String deletePolicyFromPDPGroup (OnapPDPGroup group, ONAPLoggingContext loggingContext){
412 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
413 String response = null;
414 loggingContext.setServiceName("API:PAP.DeleteHandler");
415 OnapPDPGroup existingGroup = null;
417 existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
418 } catch (PAPException e1) {
419 PolicyLogger.error("Exception occured While Deleting Policy From PDP Group"+e1);
421 if (!(group instanceof StdPDPGroup) || existingGroup == null || !(group.getId().equals(existingGroup.getId()))) {
422 String existingID = null;
423 if(existingGroup != null){
424 existingID = existingGroup.getId();
426 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingID + " objectFromJSON="+group);
427 loggingContext.transactionEnded();
428 PolicyLogger.audit("Transaction Failed - See Error.log");
429 response = "No Group";
432 // The Path on the PAP side is not carried on the RESTful interface with the AC
433 // (because it is local to the PAP)
434 // so we need to fill that in before submitting the group for update
435 ((StdPDPGroup)group).setDirectory(((StdPDPGroup)existingGroup).getDirectory());
437 acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete");
438 } catch(Exception e){
439 PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
440 +"group="+existingGroup.getId());
441 response = "DB Error";
445 XACMLPapServlet.getPAPEngine().updateGroup(group);
446 } catch (PAPException e) {
447 PolicyLogger.error("Exception occured While Updating PDP Groups"+e);
448 response = "error in updateGroup method";
450 PolicyLogger.debug("Group '" + group.getId() + "' updated");
451 acPutTransaction.commitTransaction();
452 // Group changed, which might include changing the policies
454 newgroup = existingGroup;
455 } catch (Exception e) {
456 PolicyLogger.error("Exception occured in Group Change Method"+e);
457 response = "error in groupChanged method";
460 response = "success";
461 loggingContext.transactionEnded();
462 PolicyLogger.audit("Policy successfully deleted!");
464 loggingContext.transactionEnded();
465 PolicyLogger.audit("Transaction Ended");
469 public OnapPDPGroup getDeletedGroup(){
473 public boolean preSafetyCheck(PDPPolicy policy) {
477 public static DeleteHandler getInstance() {
479 Class<?> deleteHandler = Class.forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
480 return (DeleteHandler) deleteHandler.newInstance();
481 } catch (Exception e) {
482 logger.error(e.getMessage(),e);