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