Modify ONAP PAP REST classes basic checkstyle
[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-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
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     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._]*";
68
69     public void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response) throws IOException, SQLException  {
70         // get the request content into a String
71         String json = null;
72         java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
73         scanner.useDelimiter("\\A");
74         json =  scanner.hasNext() ? scanner.next() : "";
75         scanner.close();
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;
82         int currentVersion;
83         String removeVersionExtension;
84         String splitPolicyName = null;
85         String[] split = null;
86         String status = ERROR;
87         PolicyEntity policyEntity = null;
88         JPAUtils jpaUtils = null;
89
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;
95
96         try {
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);
103             return;
104         }
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);
110             return;
111         }
112         EntityManager em = XACMLPapServlet.getEmf().createEntityManager();
113         Query policyEntityQuery = null;
114         try{
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_");
127                     }
128                     if(splitPolicyName != null){
129                         split = splitPolicyName.split(":");
130                     }else{
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 );
134                         return;
135                     }
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_");
144                     }
145                     split = splitPolicyName.split(":");
146                     queryCheck = false;
147                     policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope");
148                 }
149
150                 if(queryCheck){
151                     policyEntityQuery.setParameter("pName", "%"+split[1]+"%");
152                 }else{
153                     policyEntityQuery.setParameter("pName", split[1]);
154                 }
155
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);
163                     int newVersion = 0;
164                     em.getTransaction().begin();
165                     Class.forName(papDbDriver);
166                     con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
167
168                     if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
169                         boolean groupCheck = checkPolicyGroupEntity(con, peResult);
170                         if(!groupCheck){
171                             for(Object peData : peResult){
172                                 policyEntity = (PolicyEntity) peData;
173                                 status = deletePolicyEntityData(em, policyEntity);
174                             }
175                         }else{
176                             status = POLICY_IN_PDP;
177                         }
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 );
182                             return;
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);
187                             return;
188                         }else{
189                             try{
190                                 policyVersionDeleted = true;
191                                 em.remove(pVersion);
192                             }catch(Exception e){
193                                 logger.error(e.getMessage(),e);
194                                 policyVersionDeleted = false;
195                             }
196                         }
197                     }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")){
198                         boolean groupCheck = checkPolicyGroupEntity(con, peResult);
199                         if(!groupCheck){
200                             policyEntity = (PolicyEntity) peResult.get(0);
201                             status = deletePolicyEntityData(em, policyEntity);
202                         }else{
203                             status = POLICY_IN_PDP;
204                         }
205
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 );
210                             return;
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);
215                             return;
216                         }else{
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;
225                                         }
226                                     }
227                                 }
228                                 pVersion.setActiveVersion(newVersion);
229                                 pVersion.setHigherVersion(newVersion);
230                                 try{
231                                     policyVersionDeleted = true;
232                                     em.persist(pVersion);
233                                 }catch(Exception e){
234                                     logger.error(e.getMessage(),e);
235                                     policyVersionDeleted = false;
236                                 }
237                             }else{
238                                 try{
239                                     policyVersionDeleted = true;
240                                     em.remove(pVersion);
241                                 }catch(Exception e){
242                                     logger.error(e.getMessage(),e);
243                                     policyVersionDeleted = false;
244                                 }
245                             }
246                         }
247                     }
248                 }else{
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 );
252                     return;
253                 }
254             }
255             em.getTransaction().commit();
256         }catch(Exception e){
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);
261             return;
262         } finally {
263             em.close();
264             if(con != null){
265                 con.close();
266             }
267         }
268
269         if (policyVersionDeleted) {
270             response.setStatus(HttpServletResponse.SC_OK);
271             response.addHeader("successMapKey", "success");
272             response.addHeader("operation", "delete");
273             return;
274         } else {
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 );
278             return;
279         }
280     }
281
282     public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity){
283         PolicyElasticSearchController controller = new PolicyElasticSearchController();
284         PolicyRestAdapter policyData = new PolicyRestAdapter();
285         String policyName = policyEntity.getPolicyName();
286         try{
287             if(policyName.contains("Config_")){
288                 em.remove(policyEntity.getConfigurationData());
289             }else if(policyName.contains("Action_")){
290                 em.remove(policyEntity.getActionBodyEntity());
291             }
292             String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
293             policyData.setNewFileName(searchPolicyName);
294             controller.deleteElk(policyData);
295             em.remove(policyEntity);
296         }catch(Exception e){
297             logger.error(e.getMessage(),e);
298             return ERROR;
299         }
300         return "success";
301     }
302
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();
309                 if(gEntityList){
310                     return true;
311                 }
312             }
313         }
314         return false;
315     }
316
317     public void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws IOException {
318
319         String policyName = request.getParameter("policyName");
320         String groupId = request.getParameter("groupId");
321         String responseString = null;
322
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");
327             return;
328         }
329
330         PolicyLogger.info("JSON request from API to Delete Policy from the PDP: " + policyName);
331
332         // for PUT operations the group may or may not need to exist before the operation can be done
333         OnapPDPGroup group = null;
334         try {
335             group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
336         } catch (PAPException e) {
337             PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group"+e);
338         }
339         if (group == null) {
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);
347             return;
348         } else {
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.");
352             } else {
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);
359                 return;
360             }
361             RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
362             PDPPolicy policy =  group.getPolicy(policyName);
363             if (policy != null) {
364
365                 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
366                     if (preSafetyCheck(policy)) {
367                         PolicyLogger.debug("Precheck Successful.");
368                     }
369                 }
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);
374             } else {
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);
380                 return;
381             }
382         }
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");
390             return;
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);
397             return;
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");
402             return;
403         } else {
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 );
407             return;
408         }
409     }
410
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;
416         try {
417             existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
418         } catch (PAPException e1) {
419             PolicyLogger.error("Exception occured While Deleting Policy From PDP Group"+e1);
420         }
421         if (!(group instanceof StdPDPGroup) || existingGroup == null || !(group.getId().equals(existingGroup.getId()))) {
422             String existingID = null;
423             if(existingGroup != null){
424                 existingID = existingGroup.getId();
425             }
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";
430             return response;
431         }
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());
436         try{
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";
442             return response;
443         }
444         try {
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";
449         }
450         PolicyLogger.debug("Group '" + group.getId() + "' updated");
451         acPutTransaction.commitTransaction();
452         // Group changed, which might include changing the policies
453         try {
454             newgroup = existingGroup;
455         }  catch (Exception e) {
456             PolicyLogger.error("Exception occured in Group Change Method"+e);
457             response = "error in groupChanged method";
458         }
459         if (response==null){
460             response = "success";
461             loggingContext.transactionEnded();
462             PolicyLogger.audit("Policy successfully deleted!");
463         }
464         loggingContext.transactionEnded();
465         PolicyLogger.audit("Transaction Ended");
466         return response;
467     }
468
469     public OnapPDPGroup getDeletedGroup(){
470         return newgroup;
471     }
472
473     public boolean preSafetyCheck(PDPPolicy policy) {
474         return true;
475     }
476
477     public static DeleteHandler getInstance() {
478         try {
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);
483         }
484         return null;
485     }
486
487 }