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