Merge "Fix audit log to contain ending timestamp"
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / handler / DeleteHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20 package org.onap.policy.pap.xacml.rest.handler;
21
22 import java.io.File;
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;
30
31 import javax.persistence.EntityManager;
32 import javax.persistence.Query;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35
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;
55
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;
59
60 public class DeleteHandler {
61
62         private OnapPDPGroup newgroup;
63         private static Logger logger = FlexLogger.getLogger(DeleteHandler.class);
64
65         public void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws IOException, SQLException  {
66                 // get the request content into a String
67                 String json = null;
68                 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
69                 scanner.useDelimiter("\\A");
70                 json =  scanner.hasNext() ? scanner.next() : "";
71                 scanner.close();
72                 PolicyLogger.info("JSON request from API: " + json);
73                 // convert Object sent as JSON into local object
74                 StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
75                 String policyName = policy.getPolicyName();
76                 Boolean policyVersionDeleted = false;
77                 String removeXMLExtension;
78                 int currentVersion;
79                 String removeVersionExtension;
80                 String splitPolicyName = null;
81                 String[] split = null;
82                 String status = "error";
83                 PolicyEntity policyEntity = null;
84                 JPAUtils jpaUtils = null;
85
86                 String papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
87                 String papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
88                 String papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
89                 String papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
90                 Connection con = null;
91                 
92                 try {
93                         jpaUtils = JPAUtils.getJPAUtilsInstance(XACMLPapServlet.getEmf());
94                 } catch (Exception e) {
95                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP");
96                         response.addHeader("error", "jpautils");
97                         response.addHeader("operation", "delete");
98                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
99                         return;
100                 }
101                 if (jpaUtils.dbLockdownIgnoreErrors()) {
102                         PolicyLogger.warn("Policies are locked down");
103                         response.addHeader("operation", "delete");
104                         response.addHeader("lockdown", "true");
105                         response.setStatus(HttpServletResponse.SC_ACCEPTED);
106                         return;
107                 }
108                 EntityManager em = XACMLPapServlet.getEmf().createEntityManager();
109                 Query policyEntityQuery = null;
110                 try{
111                         if(policyName.endsWith(".xml")){
112                                 removeXMLExtension = policyName.replace(".xml", "");
113                                 currentVersion = Integer.parseInt(removeXMLExtension.substring(removeXMLExtension.lastIndexOf(".")+1));
114                                 removeVersionExtension = removeXMLExtension.substring(0, removeXMLExtension.lastIndexOf("."));
115                                 boolean queryCheck = true;
116                                 if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
117                                         if(policyName.contains("Config_")){
118                                                 splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
119                                         }else if(policyName.contains("Action_")){
120                                                 splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
121                                         }else if(policyName.contains("Decision_")){
122                                                 splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
123                                         }
124                                         if(splitPolicyName != null){
125                                                 split = splitPolicyName.split(":");
126                                         }else{
127                                                 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy. Please, provide the valid policyname.");
128                                                 response.addHeader("error", "unknown");
129                                                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
130                                                 return;
131                                         }
132                                         policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope");
133                                 }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
134                                         if(policyName.contains("Config_")){
135                                                 splitPolicyName = policyName.replace(".Config_", ":Config_");
136                                         }else if(policyName.contains("Action_")){
137                                                 splitPolicyName = policyName.replace(".Action_", ":Action_");
138                                         }else if(policyName.contains("Decision_")){
139                                                 splitPolicyName = policyName.replace(".Decision_", ":Decision_");
140                                         }
141                                         split = splitPolicyName.split(":");
142                                         queryCheck = false;
143                                         policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope");
144                                 }
145                                 
146                                 if(queryCheck){
147                                         policyEntityQuery.setParameter("pName", "%"+split[1]+"%");
148                                 }else{
149                                         policyEntityQuery.setParameter("pName", split[1]);
150                                 }
151                                 
152                                 policyEntityQuery.setParameter("pScope", split[0]);
153                                 List<?> peResult = policyEntityQuery.getResultList();
154                                 if(!peResult.isEmpty()){
155                                         Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
156                                         getPolicyVersion.setParameter("pname", removeVersionExtension.replace(".", File.separator));
157                                         List<?> pvResult = getPolicyVersion.getResultList();
158                                         PolicyVersion pVersion = (PolicyVersion) pvResult.get(0);
159                                         int newVersion = 0; 
160                                         em.getTransaction().begin();
161                                         Class.forName(papDbDriver);
162                                         con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
163                                         
164                                         if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
165                                                 boolean groupCheck = checkPolicyGroupEntity(em, con, peResult);
166                                                 if(!groupCheck){
167                                                         for(Object peData : peResult){
168                                                                 policyEntity = (PolicyEntity) peData;
169                                                                 status = deletePolicyEntityData(em, policyEntity);
170                                                         }
171                                                 }else{
172                                                         status = "PolicyInPDP";
173                                                 }
174                                                 if(status.equals("error")){
175                                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
176                                                         response.addHeader("error", "unknown");
177                                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
178                                                         return;
179                                                 }else if(status.equals("PolicyInPDP")){
180                                                         PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
181                                                         response.addHeader("error", "PolicyInPDP");
182                                                         response.setStatus(HttpServletResponse.SC_CONFLICT);
183                                                         return;
184                                                 }else{
185                                                         try{
186                                                                 policyVersionDeleted = true;
187                                                                 em.remove(pVersion);
188                                                         }catch(Exception e){
189                                                                 logger.error(e.getMessage(),e);
190                                                                 policyVersionDeleted = false;
191                                                         }
192                                                 }
193                                         }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")){
194                                                 boolean groupCheck = checkPolicyGroupEntity(em, con, peResult);
195                                                 if(!groupCheck){
196                                                         policyEntity = (PolicyEntity) peResult.get(0);
197                                                         status = deletePolicyEntityData(em, policyEntity);
198                                                 }else{
199                                                         status = "PolicyInPDP";
200                                                 }
201                                                 
202                                                 if(status.equals("error")){
203                                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
204                                                         response.addHeader("error", "unknown");
205                                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
206                                                         return;
207                                                 }else if(status.equals("PolicyInPDP")){
208                                                         PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
209                                                         response.addHeader("error", "unknown");
210                                                         response.setStatus(HttpServletResponse.SC_CONFLICT);
211                                                         return;
212                                                 }else{
213                                                         if(currentVersion > 1){
214                                                                 if(!peResult.isEmpty()){
215                                                                         for(Object object : peResult){
216                                                                                 policyEntity = (PolicyEntity) object;
217                                                                                 String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
218                                                                                 int policyEntityVersion = Integer.parseInt(policyEntityName.substring(policyEntityName.lastIndexOf(".")+1));
219                                                                                 if(policyEntityVersion > newVersion){
220                                                                                         newVersion = policyEntityVersion-1;
221                                                                                 }
222                                                                         }
223                                                                 }
224                                                                 pVersion.setActiveVersion(newVersion);
225                                                                 pVersion.setHigherVersion(newVersion);
226                                                                 try{
227                                                                         policyVersionDeleted = true;
228                                                                         em.persist(pVersion);
229                                                                 }catch(Exception e){
230                                                                         logger.error(e.getMessage(),e);
231                                                                         policyVersionDeleted = false;
232                                                                 }
233                                                         }else{
234                                                                 try{
235                                                                         policyVersionDeleted = true;
236                                                                         em.remove(pVersion);
237                                                                 }catch(Exception e){
238                                                                         logger.error(e.getMessage(),e);
239                                                                         policyVersionDeleted = false;
240                                                                 }
241                                                         }
242                                                 }
243                                         }
244                                 }else{
245                                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
246                                         response.addHeader("error", "unknown");
247                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
248                                         return;
249                                 }
250                         }
251                         em.getTransaction().commit();
252                 }catch(Exception e){
253                         em.getTransaction().rollback();
254                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
255                         response.addHeader("error", "deleteDB");
256                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
257                         return;
258                 } finally {
259                         em.close();
260                         if(con != null){
261                                 con.close();
262                         }
263                 }
264
265                 if (policyVersionDeleted) {
266                         response.setStatus(HttpServletResponse.SC_OK);
267                         response.addHeader("successMapKey", "success");
268                         response.addHeader("operation", "delete");
269                         return;                         
270                 } else {
271                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
272                         response.addHeader("error", "unknown");
273                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
274                         return;
275                 }
276         }
277         
278         public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity){
279                 PolicyElasticSearchController controller = new PolicyElasticSearchController();
280                 PolicyRestAdapter policyData = new PolicyRestAdapter();
281                 String policyName = policyEntity.getPolicyName();
282                 try{
283                         if(policyName.contains("Config_")){
284                                 em.remove(policyEntity.getConfigurationData());
285                         }else if(policyName.contains("Action_")){
286                                 em.remove(policyEntity.getActionBodyEntity());
287                         }
288                         String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
289                         policyData.setNewFileName(searchPolicyName);
290                         controller.deleteElk(policyData);
291                         em.remove(policyEntity);
292                 }catch(Exception e){
293                         logger.error(e.getMessage(),e);
294                         return "error";
295                 }
296                 return "success";
297         }
298         
299         public static boolean checkPolicyGroupEntity(EntityManager em, Connection con, List<?> peResult) throws SQLException{
300                 for(Object peData : peResult){
301                         PolicyEntity policyEntity = (PolicyEntity) peData;
302                         Statement st = null;
303                         ResultSet rs = null;
304                         try{
305                                 st = con.createStatement();
306                                 rs = st.executeQuery("Select * from PolicyGroupEntity where policyid = '"+policyEntity.getPolicyId()+"'");
307                                 boolean gEntityList = rs.next();
308                                 rs.close();
309                                 if(gEntityList){
310                                         return true;
311                                 }
312                         }finally{
313                                 if(st != null){
314                                         st.close();
315                                 }       
316                         }
317                 }
318                 return false;
319         }
320
321         public void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws IOException {
322                 String policyName = request.getParameter("policyName");
323                 String groupId = request.getParameter("groupId");
324                 String responseString = null;
325                 // for PUT operations the group may or may not need to exist before the operation can be done
326                 OnapPDPGroup group = null;
327                 try {
328                         group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
329                 } catch (PAPException e) {
330                         PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group"+e);
331                 }
332                 if (group == null) {
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.sendError(HttpServletResponse.SC_NOT_FOUND, message);
339                         return;
340                 } else {
341                         loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
342                         if (policyName.contains("xml")) {
343                                 PolicyLogger.debug("The full file name including the extension was provided for policyName.. continue.");
344                         } else {
345                                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
346                                                 + "policyName must be the full name of the file to be deleted including version and extension";
347                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
348                                                 + "policyName must be the full name of the file to be deleted including version and extension");
349                                 response.addHeader("error", message);
350                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
351                                 return;
352                         }
353                         RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
354                         PDPPolicy policy =  group.getPolicy(policyName);
355                         if (policy != null) {
356                                 
357                                 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
358                                         if (preSafetyCheck(policy)) {
359                                                 PolicyLogger.debug("Precheck Successful.");
360                                         }
361                                 }
362                                 
363                                 removePolicy.prepareToRemove(policy);
364                                 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
365                                 responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
366                         } else {
367                                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
368                                 PolicyLogger.error(message);
369                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
370                                 response.addHeader("error", message);
371                                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
372                                 return;
373                         }                       
374                 }
375                 if (responseString.equals("success")) {
376                         loggingContext.transactionEnded();
377                         PolicyLogger.info("Policy successfully deleted!");
378                         PolicyLogger.audit("Policy successfully deleted!");
379                         response.setStatus(HttpServletResponse.SC_OK);
380                         response.addHeader("successMapKey", "success");
381                         response.addHeader("operation", "delete");
382                         return;         
383                 } else if (responseString.equals("No Group")) {
384                         String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
385                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
386                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
387                         response.addHeader("error", "groupUpdate");
388                         response.addHeader("message", message);
389                         return; 
390                 } else if (responseString.equals("DB Error")) {
391                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
392                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
393                         response.addHeader("error", "deleteDB");
394                         return;
395                 } else {
396                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
397                         response.addHeader("error", "unknown");
398                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
399                         return;
400                 }
401         }
402
403         private String deletePolicyFromPDPGroup (OnapPDPGroup group, ONAPLoggingContext loggingContext){
404                 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
405                 String response = null;
406                 loggingContext.setServiceName("API:PAP.DeleteHandler");
407                 OnapPDPGroup existingGroup = null;
408                 try {
409                         existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
410                 } catch (PAPException e1) {
411                         PolicyLogger.error("Exception occured While Deleting Policy From PDP Group"+e1);
412                 }
413                 if (group == null || ! (group instanceof StdPDPGroup) || existingGroup == null || ! (group.getId().equals(existingGroup.getId()))) {
414                         String existingID = null;
415                         if(existingGroup != null){
416                                 existingID = existingGroup.getId();
417                         }
418                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingID + " objectFromJSON="+group);
419                         loggingContext.transactionEnded();
420                         PolicyLogger.audit("Transaction Failed - See Error.log");
421                         response = "No Group";
422                         return response;
423                 }
424                 // The Path on the PAP side is not carried on the RESTful interface with the AC
425                 // (because it is local to the PAP)
426                 // so we need to fill that in before submitting the group for update
427                 ((StdPDPGroup)group).setDirectory(((StdPDPGroup)existingGroup).getDirectory());
428                 try{
429                         acPutTransaction.updateGroup(group, "XACMLPapServlet.doAPIDelete");
430                 } catch(Exception e){
431                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
432                                         +"group="+existingGroup.getId());
433                         response = "DB Error";
434                         return response;
435                 }
436                 try {
437                         XACMLPapServlet.getPAPEngine().updateGroup(group);
438                 } catch (PAPException e) {
439                         PolicyLogger.error("Exception occured While Updating PDP Groups"+e);
440                         response = "error in updateGroup method";
441                 }
442                 PolicyLogger.debug("Group '" + group.getId() + "' updated");
443                 acPutTransaction.commitTransaction();
444                 // Group changed, which might include changing the policies
445                 try {
446                         newgroup = existingGroup;
447                 }  catch (Exception e) {
448                         PolicyLogger.error("Exception occured in Group Change Method"+e);
449                         response = "error in groupChanged method";
450                 }
451                 if (response==null){
452                         response = "success";
453                         loggingContext.transactionEnded();
454                         PolicyLogger.audit("Policy successfully deleted!");
455                 }
456                 loggingContext.transactionEnded();
457                 PolicyLogger.audit("Transaction Ended");
458                 return response;
459         }
460         
461         public OnapPDPGroup getDeletedGroup(){
462                 return newgroup;
463         }
464         
465         public boolean preSafetyCheck(PDPPolicy policy) {
466                 return true;
467         }
468         
469         public static DeleteHandler getInstance() {
470                 try {
471                         Class<?> deleteHandler = Class.forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
472                         return (DeleteHandler) deleteHandler.newInstance(); 
473                 } catch (Exception e) {
474                         logger.error(e.getMessage(),e);
475                 }
476                 return null;
477         }
478
479 }