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