Fix vulnerabilities and bugs in policy/engine
[policy/engine.git] / ONAP-PDP-REST / src / main / java / org / onap / policy / pdp / rest / api / services / PAPServices.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PDP-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.pdp.rest.api.services;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.ObjectInputStream;
26 import java.io.OutputStream;
27 import java.net.HttpURLConnection;
28 import java.net.URL;
29 import java.nio.charset.StandardCharsets;
30 import java.util.Arrays;
31 import java.util.Base64;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.UUID;
36
37 import org.apache.commons.io.IOUtils;
38 import org.onap.policy.api.PolicyException;
39 import org.onap.policy.common.logging.flexlogger.FlexLogger;
40 import org.onap.policy.common.logging.flexlogger.Logger;
41 import org.onap.policy.pdp.rest.config.PDPApiAuth;
42 import org.onap.policy.rest.XACMLRestProperties;
43 import org.onap.policy.utils.CryptoUtils;
44 import org.onap.policy.xacml.api.XACMLErrorConstants;
45 import org.onap.policy.xacml.std.pap.StdPDPPolicy;
46
47 import com.att.research.xacml.util.XACMLProperties;
48 import com.fasterxml.jackson.databind.ObjectMapper;
49
50 public class PAPServices {
51     private static final String SUCCESS = "success";
52     private static Logger LOGGER = FlexLogger.getLogger(PAPServices.class
53             .getName());
54     
55     private int responseCode = 0;
56     private static String environment = "DEVL";
57     private static Boolean isJunit = false;
58     private static List<String> paps = null;
59         private static final Object papResourceLock = new Object();
60     private String operation = null;
61     private String requestMethod = null;
62     private String encoding = null;
63
64     public static void setJunit(boolean isJunit) {
65         PAPServices.isJunit = isJunit;
66     }
67
68     public PAPServices() {
69         environment = PDPApiAuth.getEnvironment();
70         if(paps == null){
71             synchronized (papResourceLock) {
72                 String urlList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS);
73                 if(urlList == null){
74                     urlList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
75                 }
76                 paps = Arrays.asList(urlList.split(","));
77             }
78         }
79     }
80     
81     private String getPAPEncoding(){
82         if(encoding  == null){
83             String userID =  XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
84             String pass =CryptoUtils.decryptTxtNoExStr(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS));
85             Base64.Encoder encoder = Base64.getEncoder();
86             encoding =  encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8));
87         }
88         return encoding;
89     }
90     
91     private void rotatePAPList(){
92         synchronized (papResourceLock) {
93             Collections.rotate(paps, -1);
94         }
95     }
96     
97     private String getPAP(){
98         String result;
99         synchronized (papResourceLock) {
100             result = paps.get(0);
101         }
102         return result;
103     }
104     
105     public static void setPaps(List<String> paps) {
106                 PAPServices.paps = paps;
107         }
108
109     public int getResponseCode() {
110         return responseCode;
111     }
112
113     public Object callPAP(Object content, String[] parameters, UUID requestID,
114             String clientScope) throws PolicyException {
115         String response = null;
116         HttpURLConnection connection = null;
117         responseCode = 0;
118         // Checking for the available PAPs is done during the first Request and
119         // the List is going to have the connected PAP as first element.
120         // This makes it Real-Time to change the list depending on their
121         // availability.
122         if (paps == null || paps.isEmpty()) {
123             String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAPs List is Empty.";
124             LOGGER.error(message);
125             throw new PolicyException(message);
126         }
127         int papsCount = 0;
128         boolean connected = false;
129         while (papsCount < paps.size()) {
130             try {
131                 String fullURL = getPAP();
132                 fullURL = checkParameter(parameters, fullURL);
133                 URL url = new URL(fullURL);
134                 LOGGER.debug("--- Sending Request to PAP : "+ url.toString() + " ---");
135                 // Open the connection
136                 connection = (HttpURLConnection) url.openConnection();
137                 // Setting Content-Type
138                 connection.setRequestProperty("Content-Type","application/json");
139                 // Adding Authorization
140                 connection.setRequestProperty("Authorization", "Basic "+ getPAPEncoding());
141                 connection.setRequestProperty("Environment", environment);
142                 connection.setRequestProperty("ClientScope", clientScope);
143                 // set the method and headers
144                 connection.setRequestMethod(requestMethod);
145                 connection.setUseCaches(false);
146                 connection.setInstanceFollowRedirects(false);
147                 connection.setDoOutput(true);
148                 connection.setDoInput(true);
149                 // Adding RequestID
150                 if (requestID == null) {
151                     requestID = UUID.randomUUID();
152                     LOGGER.info("No request ID provided, sending generated ID: "
153                             + requestID.toString());
154                 } else {
155                     LOGGER.info("Using provided request ID: "
156                             + requestID.toString());
157                 }
158                 connection.setRequestProperty("X-ECOMP-RequestID",
159                         requestID.toString());
160                 if (content != null && (content instanceof InputStream)) {
161                     // send current configuration
162                     try (OutputStream os = connection.getOutputStream()) {
163                         int count = IOUtils.copy((InputStream) content, os);
164                         if (LOGGER.isDebugEnabled()) {
165                             LOGGER.debug("copied to output, bytes=" + count);
166                         }
167                     }
168                 } else if(content != null){
169                     // the content is an object to be encoded in JSON
170                     ObjectMapper mapper = new ObjectMapper();
171                     if (!isJunit) {
172                         mapper.writeValue(connection.getOutputStream(),
173                                 content);
174                     }
175                 }
176                 // DO the connect
177                 connection.connect();
178                 responseCode = connection.getResponseCode();
179                 // If Connected to PAP then break from the loop and continue
180                 // with the Request
181                 if (connection.getResponseCode() > 0 || isJunit) {
182                     connected = true;
183                     break;
184                 } else {
185                     LOGGER.debug(XACMLErrorConstants.ERROR_PERMISSIONS+ "PAP Response Code : "  + connection.getResponseCode());
186                     rotatePAPList();
187                 }
188             } catch (Exception e) {
189                 // This means that the PAP is not working
190                 if (isJunit) {
191                     connected = true;
192                     break;
193                 }
194                 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR
195                         + "PAP connection Error : " + e);
196                 rotatePAPList();
197             }
198             papsCount++;
199         }
200         if (connected) {
201             // Read the Response
202             LOGGER.debug("connected to the PAP : " + getPAP());
203             LOGGER.debug("--- Response: ---");
204             if(connection != null){
205                 Map<String, List<String>> headers = connection.getHeaderFields();
206                 for (String key : headers.keySet()) {
207                         LOGGER.debug("Header :" + key + "  Value: " + headers.get(key));
208                 }
209
210                 try {
211                         response = checkResponse(connection, requestID);
212                 } catch (IOException e) {
213                         LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
214                         response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + e;
215                         throw new PolicyException(
216                                         XACMLErrorConstants.ERROR_SYSTEM_ERROR
217                                         + "Decoding the result ", e);
218                 }
219                 if (isJunit) {
220                         response = SUCCESS;
221                 }
222             }else{
223                 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "connection is null";
224             }
225             return response;
226         } else {
227             response = XACMLErrorConstants.ERROR_DATA_ISSUE
228                     + "Unable to get valid response from PAP(s) " + paps;
229             return response;
230         }
231     }
232     
233     public String getActiveVersion(String policyScope, String filePrefix, String policyName, String clientScope, UUID requestID) {
234         String version = null;
235         HttpURLConnection connection = null;
236         String [] parameters = {"apiflag=version","policyScope="+policyScope, "filePrefix="+filePrefix, "policyName="+policyName};
237         if (paps == null || paps.isEmpty()) {
238             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PAPs List is Empty.");
239         }else {
240             int papsCount = 0;
241             boolean connected = false;
242             while (papsCount < paps.size()) {
243                 try {
244                     String fullURL = getPAP();
245                     if (parameters != null && parameters.length > 0) {
246                         String queryString = "";
247                         for (String p : parameters) {
248                             queryString += "&" + p;
249                         }
250                         fullURL += "?" + queryString.substring(1);
251                     }
252
253                     URL url = new URL (fullURL);
254
255                     //Open the connection
256                     connection = (HttpURLConnection)url.openConnection();
257
258                     // Setting Content-Type
259                     connection.setRequestProperty("Content-Type",
260                             "application/json");
261
262                     // Adding Authorization
263                     connection.setRequestProperty("Authorization", "Basic "
264                             + getPAPEncoding());
265
266                     connection.setRequestProperty("Environment", environment);
267                     connection.setRequestProperty("ClientScope", clientScope);
268
269
270                     //set the method and headers
271                     connection.setRequestMethod("GET");
272                     connection.setUseCaches(false);
273                     connection.setInstanceFollowRedirects(false);
274                     connection.setDoOutput(true);
275                     connection.setDoInput(true);
276                     connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
277
278                     //DO the connect
279                     connection.connect();
280
281                     // If Connected to PAP then break from the loop and continue with the Request 
282                     if (connection.getResponseCode() > 0) {
283                         connected = true;
284                         break;
285
286                     } else {
287                         LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error");
288                     }
289                 } catch (Exception e) {
290                     // This means that the PAP is not working 
291                     LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e);
292                     rotatePAPList();
293                 }
294                 papsCount++;
295             }
296
297             if (connected) {
298                 //Read the Response
299                 LOGGER.debug("connected to the PAP : " + getPAP());
300                 LOGGER.debug("--- Response: ---");
301                 Map<String, List<String>> headers = connection.getHeaderFields();
302                 for (String key : headers.keySet()) {
303                     LOGGER.debug("Header :" + key + "  Value: " + headers.get(key));
304                 }
305                 try {
306                     if (connection.getResponseCode() == 200) {
307                         // Check for successful creation of policy
308                         version = connection.getHeaderField("version");
309                         LOGGER.debug("ActiveVersion from the Header: " + version);
310                     } else if (connection.getResponseCode() == 403) {
311                         LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is " 
312                                 + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ");
313                         version = "pe100";
314                     } else if (connection.getResponseCode() == 404) {
315                         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is " 
316                                 + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP");
317                         version = "pe300";
318                     } else {
319                         LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST:  Error occured while getting the version from the PAP. The request may be incorrect.");
320                     }
321                 } catch (IOException e) {
322                     LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
323                 } 
324             } else {
325                 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps);
326             }   
327         }
328         return version;
329     }
330     
331     private String checkResponse(HttpURLConnection connection, UUID requestID) throws IOException {
332         String response = null;
333         if (responseCode == 200 || isJunit) {         
334             // Check for successful creation of policy
335             String isSuccess = null;
336             if (!isJunit) { // is this a junit test?
337                 isSuccess = connection.getHeaderField("successMapKey");
338                 operation = connection.getHeaderField("operation");
339             } else {
340                 isSuccess = SUCCESS;
341             }
342             if (SUCCESS.equals(isSuccess)) {
343                 if ("update".equals(operation)) {
344                     response = "Transaction ID: " + requestID + " --Policy with the name "+ connection.getHeaderField("policyName")
345                             + " was successfully updated. ";
346                     if (connection.getHeaderField("safetyChecker")!=null) {
347                         response = response 
348                                                 + "\n\nPolicy Safety Checker Warning: This closedLoopControlName "
349                                                 + "is potentially in conflict with " + connection.getHeaderField("conflictCLName") 
350                                                 +  " that already exists." + " See detailed information on ClosedLoop Pairs below: "
351                                                 +"\n\n"+connection.getHeaderField("safetyChecker");
352                     }
353                 } else if ("create".equals(operation)) {
354                         response = "Transaction ID: " + requestID + " --Policy with the name "+ connection.getHeaderField("policyName")
355                             + " was successfully created.";
356                     if (connection.getHeaderField("safetyChecker")!=null) {
357                         response = response 
358                                                 + "\n\nPolicy Safety Checker Warning: This closedLoopControlName "
359                                                 + "is potentially in conflict with " + connection.getHeaderField("conflictCLName") 
360                                                 +  " that already exists. " + "See detailed information on ClosedLoop Pairs below: "
361                                                 +"\n\n"+connection.getHeaderField("safetyChecker");
362                     }
363                 } else if ("delete".equals(operation)) {
364                     response = "Transaction ID: " + requestID + " --The policy was successfully deleted.";
365                 } else if ("import".equals(operation)) {
366                     response = "Transaction ID: " + requestID + " --The policy engine import for "+ connection.getHeaderField("service")
367                             + " was successfull.";
368                 } else if ("createDictionary".equals(operation)) {
369                     response = "Transaction ID: " + requestID + " --Dictionary Item was added successfully!";
370                 } else if ("updateDictionary".equals(operation)) {
371                     response = "Transaction ID: " + requestID + " --Dictionary Item was updated successfully!";
372                 } else if ("getDictionary".equals(operation)) {
373                     String json =  null;
374                     try {
375                         
376                         //get the json string from the response 
377                         InputStream is = connection.getInputStream();
378                             
379                         // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
380                         java.util.Scanner scanner = new java.util.Scanner(is);
381                         scanner.useDelimiter("\\A");
382                         json =  scanner.hasNext() ? scanner.next() : "";
383                         scanner.close();
384                         
385                     } catch (IOException e1) {
386                         LOGGER.error(e1.getMessage() + e1);
387                     }
388                     response = "Transaction ID: " + requestID + " --Dictionary Items Retrieved " + json;
389                 } else if ("getMetrics".equals(operation)) {
390                         response = "Transaction ID: " + requestID + " --Policy Metrics Retrieved " + connection.getHeaderField("metrics");
391                 }
392                 LOGGER.info(response);
393             } else {
394                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE
395                         + "Operation unsuccessful, unable to complete the request!";
396                 LOGGER.error(message);
397                 response = message;
398             }
399         } else if (connection.getResponseCode() == 202) {
400             if ("delete".equalsIgnoreCase(connection.getHeaderField("operation")) &&
401                     "true".equals(connection.getHeaderField("lockdown"))) {
402                 response = "Transaction ID: "
403                         + requestID
404                         + " --Policies are locked down, please try again later.";
405                 LOGGER.warn(response);
406             }
407         } else if (connection.getResponseCode() == 204) {
408             if ("push".equals(connection.getHeaderField("operation"))) {
409                 response = "Transaction ID: "
410                         + requestID
411                         + " --Policy '"
412                         + connection.getHeaderField("policyId")
413                         + "' was successfully pushed to the PDP group '"
414                         + connection.getHeaderField("groupId") + "'.";
415                 LOGGER.info(response);
416             }
417         } else if (connection.getResponseCode() == 400  && connection.getHeaderField("error") != null) {
418                 response = connection.getHeaderField("error");
419             LOGGER.error(response);
420         } else if (connection.getResponseCode() == 403) {
421             response = XACMLErrorConstants.ERROR_PERMISSIONS
422                     + "response code of the URL is "
423                     + connection.getResponseCode()
424                     + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
425             LOGGER.error(response);
426         } else if (connection.getResponseCode() == 404 && connection.getHeaderField("error") != null) {
427             if ("UnknownGroup".equals(connection.getHeaderField("error"))) {
428                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
429                         + connection.getHeaderField("message")
430                         + " Please check the pdpGroup you are requesting to push the policy to.";
431                 LOGGER.error(response);
432             } else if ("policyNotAvailableForEdit".equals(connection.getHeaderField("error"))) {
433                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
434                                 + connection.getHeaderField("message");
435             }
436         } else if (connection.getResponseCode() == 409  && connection.getHeaderField("error") != null) {
437             if ("modelExistsDB".equals(connection.getHeaderField("error"))) {
438                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
439                         + "Import Value Exist Error:  The import value "
440                         + connection.getHeaderField("service")
441                         + " already exist on the PAP. "
442                         + "Please create a new import value.";
443             } else if ("policyExists".equals(connection.getHeaderField("error"))) {
444                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
445                         + "Policy Exist Error:  The Policy "
446                         + connection.getHeaderField("policyName")
447                         + " already exist on the PAP. "
448                         + "Please create a new policy or use the update API to modify the existing one.";
449             } else if ("dictionaryItemExists".equals(connection.getHeaderField("error"))) {
450                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
451                         + "Dictionary Item Exist Error:  The Dictionary Item already exist in the database. "
452                         + "Please create a new Dictionary Item or use the update API to modify the existing one.";
453             } else if ("duplicateGroup".equals(connection.getHeaderField("error"))) {
454                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
455                         + "Group Policy Scope List Exist Error:  The Group Policy Scope List for this Dictionary Item already exist in the database. "
456                         + "Duplicate Group Policy Scope Lists for multiple groupNames is not allowed. "
457                         + "Please review the request and verify that the groupPolicyScopeListData1 is unique compared to existing groups.";
458             } else if("PolicyInPDP".equals(connection.getHeaderField("error"))){
459                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
460                         + "Policy Exist Error:  The Policy trying to be deleted is active in PDP. "
461                         + "Active PDP Polcies are not allowed to be deleted from PAP. "
462                         + "Please First remove the policy from PDP in order to successfully delete the Policy from PAP.";
463             }
464             LOGGER.error(response);
465         } else if (connection.getResponseCode() == 500 && connection.getHeaderField("error") != null) {
466             if ("jpautils".equals(connection.getHeaderField("error"))) {
467                 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
468                         + "Could not create JPAUtils instance on the PAP";
469             } else if ("deleteDB".equals(connection.getHeaderField("error"))) {
470                 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
471                         + "Failed to delete Policy from database.";
472             } else if ("deleteFile".equals(connection.getHeaderField("error"))) {
473                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
474                         + "Cannot delete the policy file";
475             } else if ("groupUpdate".equals(connection.getHeaderField("error"))) {
476                 response = connection.getHeaderField("message");
477             } else if ("unknown".equals(connection.getHeaderField("error"))) {
478                 response = XACMLErrorConstants.ERROR_UNKNOWN
479                         + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.";
480             } else if ("deleteConfig".equals(connection.getHeaderField("error"))) {
481                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
482                         + "Cannot delete the configuration or action body file in specified location.";
483             } else if ("missing".equals(connection.getHeaderField("error"))) {
484                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
485                         + "Failed to create value in database because service does match a value in file";
486             } else if ("importDB".equals(connection.getHeaderField("error"))) {
487                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
488                         + "Database errors during policy engine import";
489             } else if ("policyCopyError".equals(connection.getHeaderField("error"))) {
490                 response = XACMLErrorConstants.ERROR_PROCESS_FLOW
491                         + connection.getHeaderField("message");
492             } else if ("addGroupError".equals(connection.getHeaderField("error"))) {
493                 response = connection.getHeaderField("message");
494             } else if ("validation".equals(connection.getHeaderField("error"))){
495                 response = XACMLErrorConstants.ERROR_DATA_ISSUE
496                         + "Validation errors during policy engine " + connection.getHeaderField("operation") +
497                         " for " + connection.getHeaderField("service");
498             } else if ("error".equals(connection.getHeaderField("error"))) {
499                 response = XACMLErrorConstants.ERROR_UNKNOWN
500                         + "Could not create or update the policy for and unknown reason";
501             }else{
502                 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
503                         + "Error occured while attempting perform this operation.. "
504                         + "the request may be incorrect or the PAP is unreachable. " 
505                                 + connection.getHeaderField("error");
506             }
507             LOGGER.error(response);
508         } else {
509             response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
510                     + "Error occured while attempting perform this operation.. "
511                     + "the request may be incorrect or the PAP is unreachable.";
512             LOGGER.error(response);
513         }
514         return response;
515     }
516
517     private String checkParameter(String[] parameters, String fullURL) {
518         if (parameters != null && parameters.length > 0) {
519             String queryString = "";
520             for (String p : parameters) {
521                 queryString += "&" + p;
522                 if (p.equalsIgnoreCase("operation=post")) {
523                     requestMethod = "POST";
524                 } else if (p.equalsIgnoreCase("operation=delete")) {
525                     requestMethod = "DELETE";
526                     operation = "delete";
527                 } else if (p.equalsIgnoreCase("operation=get")) {
528                     requestMethod = "GET";
529                     operation = "get";
530                 } else if (p.equalsIgnoreCase("operation=put")||p.equalsIgnoreCase("operation=create")
531                         ||p.equalsIgnoreCase("operation=update")||p.equalsIgnoreCase("operation=createDictionary")){
532                         requestMethod = "PUT";
533                     if (p.equalsIgnoreCase("operation=create")) {
534                         operation = "create";
535                     } else if (p.equalsIgnoreCase("operation=update")) {
536                         operation = "update";
537                     } else if (p.equalsIgnoreCase("operation=createDictionary")){
538                                                 operation = "createDictionary";
539                                         }
540                 }else if (p.equalsIgnoreCase("importService=MICROSERVICE")||p.equalsIgnoreCase("importService=BRMSPARAM")){
541                         requestMethod = "PUT";
542                 }
543             }
544             fullURL += "?" + queryString.substring(1);
545         }
546         return fullURL;
547     }
548
549         public StdPDPPolicy pushPolicy(String policyScope, String filePrefix,
550                         String policyName, String clientScope, String pdpGroup,
551                         UUID requestID) throws PolicyException {
552                 String json = "{ "
553                                 + "\"apiflag\": \"api\","
554                                 + "\"policyScope\": \""+policyScope+"\","
555                                 + "\"filePrefix\": \""+filePrefix+"\","
556                                 + "\"policyName\": \""+policyName+"\","
557                                 + "\"clientScope\": \""+clientScope+"\","
558                                 + "\"pdpGroup\": \""+pdpGroup+"\"}";
559
560                 HttpURLConnection connection = null;
561         responseCode = 0;
562         if (paps == null || paps.isEmpty()) {
563             String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAPs List is Empty.";
564             LOGGER.error(message);
565             throw new PolicyException(message);
566         }
567         int papsCount = 0;
568         boolean connected = false;
569         while (papsCount < paps.size()) {
570             try {
571                 String fullURL = getPAP();
572                 fullURL = (fullURL.endsWith("/"))? fullURL+"onap/pushPolicy" : fullURL+"/onap/pushPolicy";
573                 URL url = new URL(fullURL);
574                 LOGGER.debug("--- Sending Request to PAP : "+ url.toString() + " ---");
575                 // Open the connection
576                 connection = (HttpURLConnection) url.openConnection();
577                 // Setting Content-Type
578                 connection.setRequestProperty("Content-Type","application/json");
579                 // Adding Authorization
580                 connection.setRequestProperty("Authorization", "Basic "+ getPAPEncoding());
581                 connection.setRequestProperty("Environment", environment);
582                 connection.setRequestProperty("ClientScope", clientScope);
583                 // set the method and headers
584                 connection.setRequestMethod("POST");
585                 connection.setUseCaches(false);
586                 connection.setInstanceFollowRedirects(false);
587                 connection.setDoOutput(true);
588                 // Adding RequestID
589                 if (requestID == null) {
590                     requestID = UUID.randomUUID();
591                     LOGGER.info("No request ID provided, sending generated ID: "
592                             + requestID.toString());
593                 } else {
594                     LOGGER.info("Using provided request ID: "
595                             + requestID.toString());
596                 }
597                 connection.setRequestProperty("X-ECOMP-RequestID",
598                         requestID.toString());
599                 // DO the connect
600                 try (OutputStream os = connection.getOutputStream()) {
601                     int count = IOUtils.copy(new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)), os);
602                     if (LOGGER.isDebugEnabled()) {
603                         LOGGER.debug("copied to output, bytes=" + count);
604                     }
605                 }
606                 connection.connect();
607                 responseCode = connection.getResponseCode();
608                 // If Connected to PAP then break from the loop and continue
609                 // with the Request
610                 if (connection.getResponseCode() > 0 || isJunit) {
611                     connected = true;
612                     break;
613                 } else {
614                     LOGGER.debug(XACMLErrorConstants.ERROR_PERMISSIONS+ "PAP Response Code : "  + connection.getResponseCode());
615                     rotatePAPList();
616                 }
617             } catch (Exception e) {
618                 // This means that the PAP is not working
619                 if (isJunit) {
620                     connected = true;
621                     break;
622                 }
623                 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR
624                         + "PAP connection Error : " + e);
625                 rotatePAPList();
626             }
627             papsCount++;
628         }
629         if (connected) {
630             // Read the Response
631             LOGGER.debug("connected to the PAP : " + getPAP());
632             LOGGER.debug("--- Response: ---");
633             if(connection != null){
634                 Map<String, List<String>> headers = connection.getHeaderFields();
635                 for (String key : headers.keySet()) {
636                     LOGGER.debug("Header :" + key + "  Value: " + headers.get(key));
637                 }
638                 try {
639                     if(responseCode==202){
640                         StdPDPPolicy policy = (StdPDPPolicy) new ObjectInputStream(connection.getInputStream()).readObject();
641                         return policy;
642                     }
643                 } catch (IOException | ClassNotFoundException e) {
644                     LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
645                     throw new PolicyException(
646                             XACMLErrorConstants.ERROR_SYSTEM_ERROR
647                                     + "Decoding the result ", e);
648                 }       
649             }
650             return null;
651         } else {
652             return null;
653         }
654     }
655 }