Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / java / org / openecomp / policy / utils / XACMLPolicyWriterWithPapNotify.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP Policy Engine
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
21 package org.openecomp.policy.utils;
22
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.UnsupportedEncodingException;
28 import java.net.HttpURLConnection;
29 import java.net.MalformedURLException;
30 import java.net.ProtocolException;
31 import java.net.URL;
32 import java.net.URLEncoder;
33 import java.nio.charset.StandardCharsets;
34 import java.nio.file.DirectoryNotEmptyException;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.util.Base64;
38 import java.util.UUID;
39
40 import org.openecomp.policy.rest.XACMLRestProperties;
41
42 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
43 import org.openecomp.policy.xacml.util.XACMLPolicyWriter;
44 import com.att.research.xacml.util.XACMLProperties;
45
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
48
49 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
50 import org.openecomp.policy.common.logging.flexlogger.Logger;
51
52 /**
53  * Helper static class that wraps XACMLPolicyWriter
54  * 
55  *
56  */
57 public class XACMLPolicyWriterWithPapNotify{
58         private static final Logger logger = FlexLogger.getLogger(XACMLPolicyWriterWithPapNotify.class);
59
60         /**
61          * Helper static class that does the work to write a policy set to a file on disk and notify PAP
62          * 
63          *
64          */
65         public static Path writePolicyFile(Path filename, PolicySetType policySet) {
66                 if(logger.isDebugEnabled()){
67                         logger.debug("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet)"
68                                         + "\nfilename = " + filename
69                                         + "\npolicySet = " + policySet);
70                 }
71                 //write to file
72                 Path path = XACMLPolicyWriter.writePolicyFile(filename, policySet);
73                 
74                 if(path!=null){
75                         //write to DB
76                         if(notifyPapOfCreateUpdate(filename.toAbsolutePath().toString())){
77                                 return path;
78                         }else{
79                                 //write to DB failed.  So, delete the file
80                                 try{
81                                         Files.deleteIfExists(path);
82                                 }catch(DirectoryNotEmptyException e){
83                                         //We are trying to delete a directory and it is not empty
84                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet): Files.deleteIfExists(path)"
85                                                         + "\nDirectoryNotEmptyException for path = " + path
86                                                         + "\nException message = " + e);
87                                 }catch(IOException e) {
88                                     // File permission problems are caught here.
89                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet): Files.deleteIfExists(path)"
90                                                         + "\nIOException for path = " + path
91                                                         + "\nException message = " + e);
92                                 }catch(Exception e){
93                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet): Files.deleteIfExists(path)"
94                                                         + "\nException for path = " + path
95                                                         + "\nException message = " + e);
96                                 }
97                                 return null;
98                         }
99
100                 }else{
101                         return null;
102                 }
103         }
104
105         /**
106          * Helper static class that does the work to write a policy set to an output stream and notify PAP
107          * 
108          *
109          */
110         public static void writePolicyFile(OutputStream os, PolicySetType policySet) {
111                 if(logger.isDebugEnabled()){
112                         logger.debug("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(OutputStream os, PolicySetType policySet)"
113                                         + "\nos = " + os
114                                         + "\npolicySet = " + policySet);
115                 }
116                 //Only used for writing a byte array output stream for a message.  No file is written
117                 XACMLPolicyWriter.writePolicyFile(os, policySet);
118         }
119
120         /**
121          * Helper static class that does the work to write a policy to a file on disk.
122          * 
123          *
124          */
125         public static Path writePolicyFile(Path filename, PolicyType policy) {
126                 if(logger.isDebugEnabled()){
127                         logger.debug("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicyType policy)"
128                                         + "\nfilename = " + filename
129                                         + "\npolicy = " + policy);
130                 }
131
132                 //write to file
133                 Path path = XACMLPolicyWriter.writePolicyFile(filename, policy);
134                 
135                 if(path!=null){
136                         //write to DB                   
137                         if(notifyPapOfCreateUpdate(filename.toAbsolutePath().toString())){
138                                 return path;
139                         }else{
140                                 //write to DB failed so delete the file
141                                 try{
142                                         Files.deleteIfExists(path);
143                                 }catch(DirectoryNotEmptyException e){
144                                         //We are trying to delete a directory and it is not empty
145                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet)Files.deleteIfExists(path) :"
146                                                         + "\nDirectoryNotEmptyException for path = " + path
147                                                         + "\nException message = " + e);
148                                 }catch(IOException e) {
149                                     // File permission problems are caught here.
150                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet): Files.deleteIfExists(path)"
151                                                         + "\nIOException for path = " + path
152                                                         + "\nException message = " + e);
153                                 }catch(Exception e){
154                                         logger.error("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(Path filename, PolicySetType policySet): Files.deleteIfExists(path)"
155                                                         + "\nException for path = " + path
156                                                         + "\nException message = " + e);
157                                 }
158                                 return null;
159                         }
160
161                 }else{
162                         return null;
163                 }
164         }
165
166
167         /**
168          * Helper static class that does the work to write a policy to a file on disk.
169          * 
170          *
171          */
172         public static InputStream getXmlAsInputStream(PolicyType policy) {
173                 if(logger.isDebugEnabled()){
174                         logger.debug("\nXACMLPolicyWriterWithPapNotify.getXmlAsInputStream(PolicyType policy)"
175                                         + "\npolicy = " + policy);
176                 }
177                 return XACMLPolicyWriter.getXmlAsInputStream(policy);
178         }
179         /**
180          * Helper static class that does the work to write a policy set to an output stream.
181          * 
182          *
183          */
184         public static void writePolicyFile(OutputStream os, PolicyType policy) {
185                 if(logger.isDebugEnabled()){
186                         logger.debug("\nXACMLPolicyWriterWithPapNotify.writePolicyFile(OutputStream os, PolicyType policy)"
187                                         + "\nos = " + os
188                                         + "\npolicy = " + policy);
189                 }
190                 //There are no references to this and if there were, it would most likely be used in an http message
191                 XACMLPolicyWriter.writePolicyFile(os, policy);
192         }
193
194         public static String changeFileNameInXmlWhenRenamePolicy(Path filename) {
195                 if(logger.isDebugEnabled()){
196                         logger.debug("\nXACMLPolicyWriterWithPapNotify.changeFileNameInXmlWhenRenamePolicy(Path filename)"
197                                         + "\nfilename = " + filename);
198                 }
199                 return XACMLPolicyWriter.changeFileNameInXmlWhenRenamePolicy(filename);
200         }
201         
202         public static boolean notifyPapOfPolicyRename(String oldPolicyName, String newPolicyName){
203                 if(logger.isDebugEnabled()){
204                         logger.debug("\nXACMLPolicyWriterWithPapNotify.notifyPapOfCreateUpdate(String policyToCreateUpdate) " 
205                                         + "\npolicyToCreateUpdate = " + " ");
206                 }
207                 Base64.Encoder encoder = Base64.getEncoder();
208                 String encoding = encoder.encodeToString((XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID)+":"+XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS)).getBytes(StandardCharsets.UTF_8));
209                 HttpURLConnection connection = null;
210                 UUID requestID = UUID.randomUUID();
211                 //loggingContext.setRequestID(requestID.toString());
212                 //loggingContext.transactionStarted();
213                 URL url;
214                 try {
215                         url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)+"?oldPolicyName="+ URLEncoder.encode(oldPolicyName, "UTF-8")+"&newPolicyName="+URLEncoder.encode(newPolicyName,"UTF-8"));
216                         if(logger.isDebugEnabled()){
217                                 logger.debug("\nnotifyPapOfCreateUpdate: URL = " + url);
218                         }
219                 } catch (MalformedURLException e) {
220                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
221                                         + "\nMalformedURLException message = " + e);
222                         
223                         return false;
224                 } catch (UnsupportedEncodingException e) {
225                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
226                                         + "\nUnsupportedEncodingException message = " + e);
227
228                         return false;
229                 }
230                 //
231                 // Open up the connection
232                 //
233                 try {
234                         connection = (HttpURLConnection)url.openConnection();
235                 } catch (IOException e) {
236                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
237                                         + "\nurl.openConnection() IOException message = " + e);                 
238                         return false;
239                 }
240                 //
241                 // Setup our method and headers
242                 //
243         try {
244                         connection.setRequestMethod("PUT");
245                 } catch (ProtocolException e) {
246                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
247                                         + "\nconnection.setRequestMethod(PUT) ProtocolException message = " + e);
248                         connection.disconnect();
249                         return false;
250                 }
251         connection.setRequestProperty("Authorization", "Basic " + encoding);
252                 connection.setRequestProperty("Accept", "text/x-java-properties");
253         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
254         connection.setRequestProperty("requestID", requestID.toString());
255         connection.setUseCaches(false);
256         //
257         // Adding this in. It seems the HttpUrlConnection class does NOT
258         // properly forward our headers for POST re-direction. It does so
259         // for a GET re-direction.
260         //
261         // So we need to handle this ourselves.
262         //
263         connection.setInstanceFollowRedirects(false);
264                 connection.setDoOutput(true);
265                 connection.setDoInput(true);
266         try {
267                         connection.connect();
268                 } catch (IOException e) {
269                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
270                                         + "\nconnection.connect() IOException message = " + e);
271                         connection.disconnect();
272                         return false;
273                 }
274         try {
275                 int responseCode = connection.getResponseCode();
276                 if(logger.isDebugEnabled()){
277                         logger.debug("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
278                                         + "\nconnection.getResponseCode() = " + responseCode);
279                 }
280                         if (responseCode == 200) {
281                                 connection.disconnect();
282                                 return true;
283                         } else {
284                                 connection.disconnect();
285                                 return false;
286                                 //System.out.println(connection.getResponseMessage());
287                                 //System.out.println(connection.getResponseCode());
288                                 //System.out.println(connection.g);
289                         }
290                 } catch (IOException e) {
291                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
292                                         + "\nconnection.getResponseCode() IOException message = " + e);
293                         connection.disconnect();
294                         return false;
295                 }
296         }
297         
298         public static boolean notifyPapOfDelete(String policyToDelete){
299                 Base64.Encoder encoder = Base64.getEncoder();
300                 String encoding = encoder.encodeToString((XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID)+":"+XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS)).getBytes(StandardCharsets.UTF_8));
301                 HttpURLConnection connection = null;
302                 UUID requestID = UUID.randomUUID();
303                 //loggingContext.setRequestID(requestID.toString());
304                 //loggingContext.transactionStarted();
305                 String papUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
306                 if(papUrl == null){
307                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
308                                         "PAP url property does not exist");
309                         return false;
310                 }
311                 String urlString = "";
312                 try{
313                 urlString = papUrl+"?groupId=0&isDeleteNotify=1&policyToDelete="+ URLEncoder.encode(policyToDelete, "UTF-8");
314                 } catch(UnsupportedEncodingException e){
315                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
316                                         "Invalid encoding: UTF-8", e);
317                         return false;
318                 }
319                 URL url;
320                 try {
321                         url = new URL(urlString);
322                 } catch (MalformedURLException e) {                     
323                         logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + 
324                                         "Error parsing PAP url: "
325                                                         + urlString
326                                                         , e);                           
327                         return false;
328                 }
329                 //
330                 // Open up the connection
331                 //
332                 try {
333                         connection = (HttpURLConnection)url.openConnection();
334                 } catch (IOException e) {
335                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
336                                         "Error opening HttpURLConnection to: "
337                                                         + url.toString()
338                                                         , e);                           
339                         return false;
340                 }
341                 //
342                 // Setup our method and headers
343                 //
344         try {
345                         connection.setRequestMethod("DELETE");
346                 } catch (ProtocolException e) {
347                         logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
348                                         "Invalid request method: DELETE", e);
349                         connection.disconnect();
350                         return false;
351                 }
352         connection.setRequestProperty("Authorization", "Basic " + encoding);
353                 connection.setRequestProperty("Accept", "text/x-java-properties");
354         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
355         connection.setRequestProperty("requestID", requestID.toString());
356         connection.setUseCaches(false);
357         //
358         // Adding this in. It seems the HttpUrlConnection class does NOT
359         // properly forward our headers for POST re-direction. It does so
360         // for a GET re-direction.
361         //
362         // So we need to handle this ourselves.
363         //
364         connection.setInstanceFollowRedirects(false);
365                 connection.setDoOutput(true);
366                 connection.setDoInput(true);
367         try {
368                         connection.connect();
369                 } catch (IOException e) {
370                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
371                                         "Error connecting HttpURLConnection to: "
372                                                         + connection.getURL().toString()
373                                                         , e);   
374                         connection.disconnect();
375                         return false;
376                 }
377         try {
378                         if (connection.getResponseCode() == 200) {
379                                 connection.disconnect();
380                                 //worked
381                                 return true;
382                         } else {
383                                 connection.disconnect();
384                                 return false;
385                                 //System.out.println(connection.getResponseMessage());
386                                 //System.out.println(connection.getResponseCode());
387                                 //System.out.println(connection.g);
388                         }
389                 } catch (IOException e) {
390                         logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
391                                         "Error getting HttpUrlConnection response code for: "
392                                                         + connection.getURL().toString()
393                                                         , e);
394                         connection.disconnect();
395                         return false;
396                 }
397         }
398         
399         public static boolean notifyPapOfCreateUpdate(String policyToCreateUpdate){
400                 if(logger.isDebugEnabled()){
401                         logger.debug("\nXACMLPolicyWriterWithPapNotify.notifyPapOfCreateUpdate(String policyToCreateUpdate) " 
402                                         + "\npolicyToCreateUpdate = " + policyToCreateUpdate);
403                 }
404                 Base64.Encoder encoder = Base64.getEncoder();
405                 String encoding = encoder.encodeToString((XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID)+":"+XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS)).getBytes(StandardCharsets.UTF_8));
406                 HttpURLConnection connection = null;
407                 UUID requestID = UUID.randomUUID();
408                 //loggingContext.setRequestID(requestID.toString());
409                 //loggingContext.transactionStarted();
410                 URL url;
411                 try {
412                         url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)+"?policyToCreateUpdate="+ URLEncoder.encode(policyToCreateUpdate, "UTF-8"));
413                         if(logger.isDebugEnabled()){
414                                 logger.debug("\nnotifyPapOfCreateUpdate: URL = " + url);
415                         }
416                 } catch (MalformedURLException e) {
417                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
418                                         + "\nMalformedURLException message = " + e);
419                         
420                         return false;
421                 } catch (UnsupportedEncodingException e) {
422                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
423                                         + "\nUnsupportedEncodingException message = " + e);
424
425                         return false;
426                 }
427                 //
428                 // Open up the connection
429                 //
430                 try {
431                         connection = (HttpURLConnection)url.openConnection();
432                 } catch (IOException e) {
433                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
434                                         + "\nurl.openConnection() IOException message = " + e);                 
435                         return false;
436                 }
437                 //
438                 // Setup our method and headers
439                 //
440         try {
441                         connection.setRequestMethod("PUT");
442                 } catch (ProtocolException e) {
443                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
444                                         + "\nconnection.setRequestMethod(PUT) ProtocolException message = " + e);
445                         connection.disconnect();
446                         return false;
447                 }
448         connection.setRequestProperty("Authorization", "Basic " + encoding);
449                 connection.setRequestProperty("Accept", "text/x-java-properties");
450         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
451         connection.setRequestProperty("requestID", requestID.toString());
452         connection.setUseCaches(false);
453         //
454         // Adding this in. It seems the HttpUrlConnection class does NOT
455         // properly forward our headers for POST re-direction. It does so
456         // for a GET re-direction.
457         //
458         // So we need to handle this ourselves.
459         //
460         connection.setInstanceFollowRedirects(false);
461                 connection.setDoOutput(true);
462                 connection.setDoInput(true);
463         try {
464                         connection.connect();
465                 } catch (IOException e) {
466                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
467                                         + "\nconnection.connect() IOException message = " + e);
468                         connection.disconnect();
469                         return false;
470                 }
471         try {
472                 int responseCode = connection.getResponseCode();
473                 if(logger.isDebugEnabled()){
474                         logger.debug("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
475                                         + "\nconnection.getResponseCode() = " + responseCode);
476                 }
477                         if (responseCode == 200) {
478                                 connection.disconnect();
479                                 return true;
480                         } else {
481                                 connection.disconnect();
482                                 return false;
483                                 //System.out.println(connection.getResponseMessage());
484                                 //System.out.println(connection.getResponseCode());
485                                 //System.out.println(connection.g);
486                         }
487                 } catch (IOException e) {
488                         logger.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
489                                         + "\nconnection.getResponseCode() IOException message = " + e);
490                         connection.disconnect();
491                         return false;
492                 }
493         }
494 }