[POLICY-73] replace openecomp for policy-engine
[policy/engine.git] / POLICY-SDK-APP / src / main / java / org / onap / policy / utils / XACMLPolicyWriterWithPapNotify.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP 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.onap.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.onap.policy.rest.XACMLRestProperties;
41
42 import org.onap.policy.xacml.api.XACMLErrorConstants;
43 import org.onap.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.onap.policy.common.logging.flexlogger.FlexLogger; 
50 import org.onap.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                 URL url;
212                 try {
213                         url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)+"?oldPolicyName="+ URLEncoder.encode(oldPolicyName, "UTF-8")+"&newPolicyName="+URLEncoder.encode(newPolicyName,"UTF-8"));
214                         if(LOGGER.isDebugEnabled()){
215                                 LOGGER.debug("\nnotifyPapOfCreateUpdate: URL = " + url);
216                         }
217                 } catch (MalformedURLException e) {
218                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
219                                         + "\nMalformedURLException message = " + e);
220                         
221                         return false;
222                 } catch (UnsupportedEncodingException e) {
223                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
224                                         + "\nUnsupportedEncodingException message = " + e);
225
226                         return false;
227                 }
228                 //
229                 // Open up the connection
230                 //
231                 try {
232                         connection = (HttpURLConnection)url.openConnection();
233                 } catch (IOException e) {
234                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
235                                         + "\nurl.openConnection() IOException message = " + e);                 
236                         return false;
237                 }
238                 //
239                 // Setup our method and headers
240                 //
241         try {
242                         connection.setRequestMethod("PUT");
243                 } catch (ProtocolException e) {
244                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
245                                         + "\nconnection.setRequestMethod(PUT) ProtocolException message = " + e);
246                         connection.disconnect();
247                         return false;
248                 }
249         connection.setRequestProperty("Authorization", "Basic " + encoding);
250                 connection.setRequestProperty("Accept", "text/x-java-properties");
251         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
252         connection.setRequestProperty("requestID", requestID.toString());
253         connection.setUseCaches(false);
254         //
255         // Adding this in. It seems the HttpUrlConnection class does NOT
256         // properly forward our headers for POST re-direction. It does so
257         // for a GET re-direction.
258         //
259         // So we need to handle this ourselves.
260         //
261         connection.setInstanceFollowRedirects(false);
262                 connection.setDoOutput(true);
263                 connection.setDoInput(true);
264         try {
265                         connection.connect();
266                 } catch (IOException e) {
267                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
268                                         + "\nconnection.connect() IOException message = " + e);
269                         connection.disconnect();
270                         return false;
271                 }
272         try {
273                 int responseCode = connection.getResponseCode();
274                 if(LOGGER.isDebugEnabled()){
275                         LOGGER.debug("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
276                                         + "\nconnection.getResponseCode() = " + responseCode);
277                 }
278                         if (responseCode == 200) {
279                                 connection.disconnect();
280                                 return true;
281                         } else {
282                                 connection.disconnect();
283                                 return false;
284                         }
285                 } catch (IOException e) {
286                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
287                                         + "\nconnection.getResponseCode() IOException message = " + e);
288                         connection.disconnect();
289                         return false;
290                 }
291         }
292         
293         public static boolean notifyPapOfDelete(String policyToDelete){
294                 Base64.Encoder encoder = Base64.getEncoder();
295                 String encoding = encoder.encodeToString((XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID)+":"+XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS)).getBytes(StandardCharsets.UTF_8));
296                 HttpURLConnection connection = null;
297                 UUID requestID = UUID.randomUUID();
298                 //loggingContext.setRequestID(requestID.toString());
299                 //loggingContext.transactionStarted();
300                 String papUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
301                 if(papUrl == null){
302                         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
303                                         "PAP url property does not exist");
304                         return false;
305                 }
306                 String urlString = "";
307                 try{
308                 urlString = papUrl+"?groupId=0&isDeleteNotify=1&policyToDelete="+ URLEncoder.encode(policyToDelete, "UTF-8");
309                 } catch(UnsupportedEncodingException e){
310                         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
311                                         "Invalid encoding: UTF-8", e);
312                         return false;
313                 }
314                 URL url;
315                 try {
316                         url = new URL(urlString);
317                 } catch (MalformedURLException e) {                     
318                         LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + 
319                                         "Error parsing PAP url: "
320                                                         + urlString
321                                                         , e);                           
322                         return false;
323                 }
324                 //
325                 // Open up the connection
326                 //
327                 try {
328                         connection = (HttpURLConnection)url.openConnection();
329                 } catch (IOException e) {
330                         LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
331                                         "Error opening HttpURLConnection to: "
332                                                         + url.toString()
333                                                         , e);                           
334                         return false;
335                 }
336                 //
337                 // Setup our method and headers
338                 //
339         try {
340                         connection.setRequestMethod("DELETE");
341                 } catch (ProtocolException e) {
342                         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + 
343                                         "Invalid request method: DELETE", e);
344                         connection.disconnect();
345                         return false;
346                 }
347         connection.setRequestProperty("Authorization", "Basic " + encoding);
348                 connection.setRequestProperty("Accept", "text/x-java-properties");
349         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
350         connection.setRequestProperty("requestID", requestID.toString());
351         connection.setUseCaches(false);
352         //
353         // Adding this in. It seems the HttpUrlConnection class does NOT
354         // properly forward our headers for POST re-direction. It does so
355         // for a GET re-direction.
356         //
357         // So we need to handle this ourselves.
358         //
359         connection.setInstanceFollowRedirects(false);
360                 connection.setDoOutput(true);
361                 connection.setDoInput(true);
362         try {
363                         connection.connect();
364                 } catch (IOException e) {
365                         LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
366                                         "Error connecting HttpURLConnection to: "
367                                                         + connection.getURL().toString()
368                                                         , e);   
369                         connection.disconnect();
370                         return false;
371                 }
372         try {
373                         if (connection.getResponseCode() == 200) {
374                                 connection.disconnect();
375                                 //worked
376                                 return true;
377                         } else {
378                                 connection.disconnect();
379                                 return false;
380                         }
381                 } catch (IOException e) {
382                         LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + 
383                                         "Error getting HttpUrlConnection response code for: "
384                                                         + connection.getURL().toString()
385                                                         , e);
386                         connection.disconnect();
387                         return false;
388                 }
389         }
390         
391         public static boolean notifyPapOfCreateUpdate(String policyToCreateUpdate){
392                 if(LOGGER.isDebugEnabled()){
393                         LOGGER.debug("\nXACMLPolicyWriterWithPapNotify.notifyPapOfCreateUpdate(String policyToCreateUpdate) " 
394                                         + "\npolicyToCreateUpdate = " + policyToCreateUpdate);
395                 }
396                 Base64.Encoder encoder = Base64.getEncoder();
397                 String encoding = encoder.encodeToString((XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID)+":"+XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS)).getBytes(StandardCharsets.UTF_8));
398                 HttpURLConnection connection = null;
399                 UUID requestID = UUID.randomUUID();
400                 //loggingContext.setRequestID(requestID.toString());
401                 //loggingContext.transactionStarted();
402                 URL url;
403                 try {
404                         url = new URL(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL)+"?policyToCreateUpdate="+ URLEncoder.encode(policyToCreateUpdate, "UTF-8"));
405                         if(LOGGER.isDebugEnabled()){
406                                 LOGGER.debug("\nnotifyPapOfCreateUpdate: URL = " + url);
407                         }
408                 } catch (MalformedURLException e) {
409                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
410                                         + "\nMalformedURLException message = " + e);
411                         
412                         return false;
413                 } catch (UnsupportedEncodingException e) {
414                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
415                                         + "\nUnsupportedEncodingException message = " + e);
416
417                         return false;
418                 }
419                 //
420                 // Open up the connection
421                 //
422                 try {
423                         connection = (HttpURLConnection)url.openConnection();
424                 } catch (IOException e) {
425                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
426                                         + "\nurl.openConnection() IOException message = " + e);                 
427                         return false;
428                 }
429                 //
430                 // Setup our method and headers
431                 //
432         try {
433                         connection.setRequestMethod("PUT");
434                 } catch (ProtocolException e) {
435                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
436                                         + "\nconnection.setRequestMethod(PUT) ProtocolException message = " + e);
437                         connection.disconnect();
438                         return false;
439                 }
440         connection.setRequestProperty("Authorization", "Basic " + encoding);
441                 connection.setRequestProperty("Accept", "text/x-java-properties");
442         connection.setRequestProperty("Content-Type", "text/x-java-properties");                        
443         connection.setRequestProperty("requestID", requestID.toString());
444         connection.setUseCaches(false);
445         //
446         // Adding this in. It seems the HttpUrlConnection class does NOT
447         // properly forward our headers for POST re-direction. It does so
448         // for a GET re-direction.
449         //
450         // So we need to handle this ourselves.
451         //
452         connection.setInstanceFollowRedirects(false);
453                 connection.setDoOutput(true);
454                 connection.setDoInput(true);
455         try {
456                         connection.connect();
457                 } catch (IOException e) {
458                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
459                                         + "\nconnection.connect() IOException message = " + e);
460                         connection.disconnect();
461                         return false;
462                 }
463         try {
464                 int responseCode = connection.getResponseCode();
465                 if(LOGGER.isDebugEnabled()){
466                         LOGGER.debug("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
467                                         + "\nconnection.getResponseCode() = " + responseCode);
468                 }
469                         if (responseCode == 200) {
470                                 connection.disconnect();
471                                 return true;
472                         } else {
473                                 connection.disconnect();
474                                 return false;
475                         }
476                 } catch (IOException e) {
477                         LOGGER.error("\nnotifyPapOfCreateUpdate(String policyToCreateUpdate)"
478                                         + "\nconnection.getResponseCode() IOException message = " + e);
479                         connection.disconnect();
480                         return false;
481                 }
482         }
483 }