2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.policy.pdp.rest.api.services;
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;
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;
35 import java.util.UUID;
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;
47 import com.att.research.xacml.util.XACMLProperties;
48 import com.fasterxml.jackson.databind.ObjectMapper;
50 public class PAPServices {
51 private static final String SUCCESS = "success";
52 private static Logger LOGGER = FlexLogger.getLogger(PAPServices.class
55 private int responseCode = 0;
56 private static String environment = "DEVL";
57 public static Boolean junit = 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;
64 public PAPServices() {
65 environment = PDPApiAuth.getEnvironment();
67 synchronized (papResourceLock) {
68 String urlList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URLS);
70 urlList = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_URL);
72 paps = Arrays.asList(urlList.split(","));
77 private String getPAPEncoding(){
79 String userID = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_USERID);
80 String pass =CryptoUtils.decryptTxtNoExStr(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_PASS));
81 Base64.Encoder encoder = Base64.getEncoder();
82 encoding = encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8));
87 private void rotatePAPList(){
88 synchronized (papResourceLock) {
89 Collections.rotate(paps, -1);
93 private String getPAP(){
95 synchronized (papResourceLock) {
101 public static void setPaps(List<String> paps) {
102 PAPServices.paps = paps;
105 public int getResponseCode() {
109 public Object callPAP(Object content, String[] parameters, UUID requestID,
110 String clientScope) throws PolicyException {
111 String response = null;
112 HttpURLConnection connection = null;
114 // Checking for the available PAPs is done during the first Request and
115 // the List is going to have the connected PAP as first element.
116 // This makes it Real-Time to change the list depending on their
118 if (paps == null || paps.isEmpty()) {
119 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAPs List is Empty.";
120 LOGGER.error(message);
121 throw new PolicyException(message);
124 boolean connected = false;
125 while (papsCount < paps.size()) {
127 String fullURL = getPAP();
128 fullURL = checkParameter(parameters, fullURL);
129 URL url = new URL(fullURL);
130 LOGGER.debug("--- Sending Request to PAP : "+ url.toString() + " ---");
131 // Open the connection
132 connection = (HttpURLConnection) url.openConnection();
133 // Setting Content-Type
134 connection.setRequestProperty("Content-Type","application/json");
135 // Adding Authorization
136 connection.setRequestProperty("Authorization", "Basic "+ getPAPEncoding());
137 connection.setRequestProperty("Environment", environment);
138 connection.setRequestProperty("ClientScope", clientScope);
139 // set the method and headers
140 connection.setRequestMethod(requestMethod);
141 connection.setUseCaches(false);
142 connection.setInstanceFollowRedirects(false);
143 connection.setDoOutput(true);
144 connection.setDoInput(true);
146 if (requestID == null) {
147 requestID = UUID.randomUUID();
148 LOGGER.info("No request ID provided, sending generated ID: "
149 + requestID.toString());
151 LOGGER.info("Using provided request ID: "
152 + requestID.toString());
154 connection.setRequestProperty("X-ECOMP-RequestID",
155 requestID.toString());
156 if (content != null && (content instanceof InputStream)) {
157 // send current configuration
158 try (OutputStream os = connection.getOutputStream()) {
159 int count = IOUtils.copy((InputStream) content, os);
160 if (LOGGER.isDebugEnabled()) {
161 LOGGER.debug("copied to output, bytes=" + count);
164 } else if(content != null){
165 // the content is an object to be encoded in JSON
166 ObjectMapper mapper = new ObjectMapper();
168 mapper.writeValue(connection.getOutputStream(),
173 connection.connect();
174 responseCode = connection.getResponseCode();
175 // If Connected to PAP then break from the loop and continue
177 if (connection.getResponseCode() > 0 || junit) {
181 LOGGER.debug(XACMLErrorConstants.ERROR_PERMISSIONS+ "PAP Response Code : " + connection.getResponseCode());
184 } catch (Exception e) {
185 // This means that the PAP is not working
190 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR
191 + "PAP connection Error : " + e);
198 LOGGER.debug("connected to the PAP : " + getPAP());
199 LOGGER.debug("--- Response: ---");
200 if(connection != null){
201 Map<String, List<String>> headers = connection.getHeaderFields();
202 for (String key : headers.keySet()) {
203 LOGGER.debug("Header :" + key + " Value: " + headers.get(key));
207 response = checkResponse(connection, requestID);
208 } catch (IOException e) {
209 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
210 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + e;
211 throw new PolicyException(
212 XACMLErrorConstants.ERROR_SYSTEM_ERROR
213 + "Decoding the result ", e);
219 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "connection is null";
223 response = XACMLErrorConstants.ERROR_DATA_ISSUE
224 + "Unable to get valid response from PAP(s) " + paps;
229 public String getActiveVersion(String policyScope, String filePrefix, String policyName, String clientScope, UUID requestID) {
230 String version = null;
231 HttpURLConnection connection = null;
232 String [] parameters = {"apiflag=version","policyScope="+policyScope, "filePrefix="+filePrefix, "policyName="+policyName};
233 if (paps == null || paps.isEmpty()) {
234 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PAPs List is Empty.");
237 boolean connected = false;
238 while (papsCount < paps.size()) {
240 String fullURL = getPAP();
241 if (parameters != null && parameters.length > 0) {
242 String queryString = "";
243 for (String p : parameters) {
244 queryString += "&" + p;
246 fullURL += "?" + queryString.substring(1);
249 URL url = new URL (fullURL);
251 //Open the connection
252 connection = (HttpURLConnection)url.openConnection();
254 // Setting Content-Type
255 connection.setRequestProperty("Content-Type",
258 // Adding Authorization
259 connection.setRequestProperty("Authorization", "Basic "
262 connection.setRequestProperty("Environment", environment);
263 connection.setRequestProperty("ClientScope", clientScope);
266 //set the method and headers
267 connection.setRequestMethod("GET");
268 connection.setUseCaches(false);
269 connection.setInstanceFollowRedirects(false);
270 connection.setDoOutput(true);
271 connection.setDoInput(true);
272 connection.setRequestProperty("X-ECOMP-RequestID", requestID.toString());
275 connection.connect();
277 // If Connected to PAP then break from the loop and continue with the Request
278 if (connection.getResponseCode() > 0) {
283 LOGGER.debug(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error");
285 } catch (Exception e) {
286 // This means that the PAP is not working
287 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAP connection Error : " + e);
295 LOGGER.debug("connected to the PAP : " + getPAP());
296 LOGGER.debug("--- Response: ---");
297 Map<String, List<String>> headers = connection.getHeaderFields();
298 for (String key : headers.keySet()) {
299 LOGGER.debug("Header :" + key + " Value: " + headers.get(key));
302 if (connection.getResponseCode() == 200) {
303 // Check for successful creation of policy
304 version = connection.getHeaderField("version");
305 LOGGER.debug("ActiveVersion from the Header: " + version);
306 } else if (connection.getResponseCode() == 403) {
307 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + "response code of the URL is "
308 + connection.getResponseCode() + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ");
310 } else if (connection.getResponseCode() == 404) {
311 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "response code of the URL is "
312 + connection.getResponseCode() + ". This indicates a problem with getting the version from the PAP");
315 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "BAD REQUEST: Error occured while getting the version from the PAP. The request may be incorrect.");
317 } catch (IOException e) {
318 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
321 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Unable to get valid response from PAP(s) " + paps);
327 private String checkResponse(HttpURLConnection connection, UUID requestID) throws IOException {
328 String response = null;
329 if (responseCode == 200 || junit) {
330 // Check for successful creation of policy
331 String isSuccess = null;
332 if (!junit) { // is this a junit test?
333 isSuccess = connection.getHeaderField("successMapKey");
334 operation = connection.getHeaderField("operation");
338 if (SUCCESS.equals(isSuccess)) {
339 if ("update".equals(operation)) {
340 response = "Transaction ID: " + requestID + " --Policy with the name "+ connection.getHeaderField("policyName")
341 + " was successfully updated. ";
342 if (connection.getHeaderField("safetyChecker")!=null) {
344 + "\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");
349 } else if ("create".equals(operation)) {
350 response = "Transaction ID: " + requestID + " --Policy with the name "+ connection.getHeaderField("policyName")
351 + " was successfully created.";
352 if (connection.getHeaderField("safetyChecker")!=null) {
354 + "\n\nPolicy Safety Checker Warning: This closedLoopControlName "
355 + "is potentially in conflict with " + connection.getHeaderField("conflictCLName")
356 + " that already exists. " + "See detailed information on ClosedLoop Pairs below: "
357 +"\n\n"+connection.getHeaderField("safetyChecker");
359 } else if ("delete".equals(operation)) {
360 response = "Transaction ID: " + requestID + " --The policy was successfully deleted.";
361 } else if ("import".equals(operation)) {
362 response = "Transaction ID: " + requestID + " --The policy engine import for "+ connection.getHeaderField("service")
363 + " was successfull.";
364 } else if ("createDictionary".equals(operation)) {
365 response = "Transaction ID: " + requestID + " --Dictionary Item was added successfully!";
366 } else if ("updateDictionary".equals(operation)) {
367 response = "Transaction ID: " + requestID + " --Dictionary Item was updated successfully!";
368 } else if ("getDictionary".equals(operation)) {
372 //get the json string from the response
373 InputStream is = connection.getInputStream();
375 // read the inputStream into a buffer (trick found online scans entire input looking for end-of-file)
376 java.util.Scanner scanner = new java.util.Scanner(is);
377 scanner.useDelimiter("\\A");
378 json = scanner.hasNext() ? scanner.next() : "";
381 } catch (IOException e1) {
382 LOGGER.error(e1.getMessage() + e1);
384 response = "Transaction ID: " + requestID + " --Dictionary Items Retrieved " + json;
385 } else if ("getMetrics".equals(operation)) {
386 response = "Transaction ID: " + requestID + " --Policy Metrics Retrieved " + connection.getHeaderField("metrics");
388 LOGGER.info(response);
390 String message = XACMLErrorConstants.ERROR_DATA_ISSUE
391 + "Operation unsuccessful, unable to complete the request!";
392 LOGGER.error(message);
395 } else if (connection.getResponseCode() == 202) {
396 if ("delete".equalsIgnoreCase(connection.getHeaderField("operation")) &&
397 "true".equals(connection.getHeaderField("lockdown"))) {
398 response = "Transaction ID: "
400 + " --Policies are locked down, please try again later.";
401 LOGGER.warn(response);
403 } else if (connection.getResponseCode() == 204) {
404 if ("push".equals(connection.getHeaderField("operation"))) {
405 response = "Transaction ID: "
408 + connection.getHeaderField("policyId")
409 + "' was successfully pushed to the PDP group '"
410 + connection.getHeaderField("groupId") + "'.";
411 LOGGER.info(response);
413 } else if (connection.getResponseCode() == 400 && connection.getHeaderField("error") != null) {
414 response = connection.getHeaderField("error");
415 LOGGER.error(response);
416 } else if (connection.getResponseCode() == 403) {
417 response = XACMLErrorConstants.ERROR_PERMISSIONS
418 + "response code of the URL is "
419 + connection.getResponseCode()
420 + ". PEP is not Authorized for making this Request!! \n Contact Administrator for this Scope. ";
421 LOGGER.error(response);
422 } else if (connection.getResponseCode() == 404 && connection.getHeaderField("error") != null) {
423 if ("UnknownGroup".equals(connection.getHeaderField("error"))) {
424 response = XACMLErrorConstants.ERROR_DATA_ISSUE
425 + connection.getHeaderField("message")
426 + " Please check the pdpGroup you are requesting to push the policy to.";
427 LOGGER.error(response);
428 } else if ("policyNotAvailableForEdit".equals(connection.getHeaderField("error"))) {
429 response = XACMLErrorConstants.ERROR_DATA_ISSUE
430 + connection.getHeaderField("message");
432 } else if (connection.getResponseCode() == 409 && connection.getHeaderField("error") != null) {
433 if ("modelExistsDB".equals(connection.getHeaderField("error"))) {
434 response = XACMLErrorConstants.ERROR_DATA_ISSUE
435 + "Import Value Exist Error: The import value "
436 + connection.getHeaderField("service")
437 + " already exist on the PAP. "
438 + "Please create a new import value.";
439 } else if ("policyExists".equals(connection.getHeaderField("error"))) {
440 response = XACMLErrorConstants.ERROR_DATA_ISSUE
441 + "Policy Exist Error: The Policy "
442 + connection.getHeaderField("policyName")
443 + " already exist on the PAP. "
444 + "Please create a new policy or use the update API to modify the existing one.";
445 } else if ("dictionaryItemExists".equals(connection.getHeaderField("error"))) {
446 response = XACMLErrorConstants.ERROR_DATA_ISSUE
447 + "Dictionary Item Exist Error: The Dictionary Item already exist in the database. "
448 + "Please create a new Dictionary Item or use the update API to modify the existing one.";
449 } else if ("duplicateGroup".equals(connection.getHeaderField("error"))) {
450 response = XACMLErrorConstants.ERROR_DATA_ISSUE
451 + "Group Policy Scope List Exist Error: The Group Policy Scope List for this Dictionary Item already exist in the database. "
452 + "Duplicate Group Policy Scope Lists for multiple groupNames is not allowed. "
453 + "Please review the request and verify that the groupPolicyScopeListData1 is unique compared to existing groups.";
454 } else if("PolicyInPDP".equals(connection.getHeaderField("error"))){
455 response = XACMLErrorConstants.ERROR_DATA_ISSUE
456 + "Policy Exist Error: The Policy trying to be deleted is active in PDP. "
457 + "Active PDP Polcies are not allowed to be deleted from PAP. "
458 + "Please First remove the policy from PDP in order to successfully delete the Policy from PAP.";
460 LOGGER.error(response);
461 } else if (connection.getResponseCode() == 500 && connection.getHeaderField("error") != null) {
462 if ("jpautils".equals(connection.getHeaderField("error"))) {
463 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
464 + "Could not create JPAUtils instance on the PAP";
465 } else if ("deleteDB".equals(connection.getHeaderField("error"))) {
466 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
467 + "Failed to delete Policy from database.";
468 } else if ("deleteFile".equals(connection.getHeaderField("error"))) {
469 response = XACMLErrorConstants.ERROR_DATA_ISSUE
470 + "Cannot delete the policy file";
471 } else if ("groupUpdate".equals(connection.getHeaderField("error"))) {
472 response = connection.getHeaderField("message");
473 } else if ("unknown".equals(connection.getHeaderField("error"))) {
474 response = XACMLErrorConstants.ERROR_UNKNOWN
475 + "Failed to delete the policy for an unknown reason. Check the file system and other logs for further information.";
476 } else if ("deleteConfig".equals(connection.getHeaderField("error"))) {
477 response = XACMLErrorConstants.ERROR_DATA_ISSUE
478 + "Cannot delete the configuration or action body file in specified location.";
479 } else if ("missing".equals(connection.getHeaderField("error"))) {
480 response = XACMLErrorConstants.ERROR_DATA_ISSUE
481 + "Failed to create value in database because service does match a value in file";
482 } else if ("importDB".equals(connection.getHeaderField("error"))) {
483 response = XACMLErrorConstants.ERROR_DATA_ISSUE
484 + "Database errors during policy engine import";
485 } else if ("policyCopyError".equals(connection.getHeaderField("error"))) {
486 response = XACMLErrorConstants.ERROR_PROCESS_FLOW
487 + connection.getHeaderField("message");
488 } else if ("addGroupError".equals(connection.getHeaderField("error"))) {
489 response = connection.getHeaderField("message");
490 } else if ("validation".equals(connection.getHeaderField("error"))){
491 response = XACMLErrorConstants.ERROR_DATA_ISSUE
492 + "Validation errors during policy engine " + connection.getHeaderField("operation") +
493 " for " + connection.getHeaderField("service");
494 } else if ("error".equals(connection.getHeaderField("error"))) {
495 response = XACMLErrorConstants.ERROR_UNKNOWN
496 + "Could not create or update the policy for and unknown reason";
498 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
499 + "Error occured while attempting perform this operation.. "
500 + "the request may be incorrect or the PAP is unreachable. "
501 + connection.getHeaderField("error");
503 LOGGER.error(response);
505 response = XACMLErrorConstants.ERROR_SYSTEM_ERROR
506 + "Error occured while attempting perform this operation.. "
507 + "the request may be incorrect or the PAP is unreachable.";
508 LOGGER.error(response);
513 private String checkParameter(String[] parameters, String fullURL) {
514 if (parameters != null && parameters.length > 0) {
515 String queryString = "";
516 for (String p : parameters) {
517 queryString += "&" + p;
518 if (p.equalsIgnoreCase("operation=post")) {
519 requestMethod = "POST";
520 } else if (p.equalsIgnoreCase("operation=delete")) {
521 requestMethod = "DELETE";
522 operation = "delete";
523 } else if (p.equalsIgnoreCase("operation=get")) {
524 requestMethod = "GET";
526 } else if (p.equalsIgnoreCase("operation=put")||p.equalsIgnoreCase("operation=create")
527 ||p.equalsIgnoreCase("operation=update")||p.equalsIgnoreCase("operation=createDictionary")){
528 requestMethod = "PUT";
529 if (p.equalsIgnoreCase("operation=create")) {
530 operation = "create";
531 } else if (p.equalsIgnoreCase("operation=update")) {
532 operation = "update";
533 } else if (p.equalsIgnoreCase("operation=createDictionary")){
534 operation = "createDictionary";
536 }else if (p.equalsIgnoreCase("importService=MICROSERVICE")||p.equalsIgnoreCase("importService=BRMSPARAM")){
537 requestMethod = "PUT";
540 fullURL += "?" + queryString.substring(1);
545 public StdPDPPolicy pushPolicy(String policyScope, String filePrefix,
546 String policyName, String clientScope, String pdpGroup,
547 UUID requestID) throws PolicyException {
549 + "\"apiflag\": \"api\","
550 + "\"policyScope\": \""+policyScope+"\","
551 + "\"filePrefix\": \""+filePrefix+"\","
552 + "\"policyName\": \""+policyName+"\","
553 + "\"clientScope\": \""+clientScope+"\","
554 + "\"pdpGroup\": \""+pdpGroup+"\"}";
556 HttpURLConnection connection = null;
558 if (paps == null || paps.isEmpty()) {
559 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR + "PAPs List is Empty.";
560 LOGGER.error(message);
561 throw new PolicyException(message);
564 boolean connected = false;
565 while (papsCount < paps.size()) {
567 String fullURL = getPAP();
568 fullURL = (fullURL.endsWith("/"))? fullURL+"onap/pushPolicy" : fullURL+"/onap/pushPolicy";
569 URL url = new URL(fullURL);
570 LOGGER.debug("--- Sending Request to PAP : "+ url.toString() + " ---");
571 // Open the connection
572 connection = (HttpURLConnection) url.openConnection();
573 // Setting Content-Type
574 connection.setRequestProperty("Content-Type","application/json");
575 // Adding Authorization
576 connection.setRequestProperty("Authorization", "Basic "+ getPAPEncoding());
577 connection.setRequestProperty("Environment", environment);
578 connection.setRequestProperty("ClientScope", clientScope);
579 // set the method and headers
580 connection.setRequestMethod("POST");
581 connection.setUseCaches(false);
582 connection.setInstanceFollowRedirects(false);
583 connection.setDoOutput(true);
585 if (requestID == null) {
586 requestID = UUID.randomUUID();
587 LOGGER.info("No request ID provided, sending generated ID: "
588 + requestID.toString());
590 LOGGER.info("Using provided request ID: "
591 + requestID.toString());
593 connection.setRequestProperty("X-ECOMP-RequestID",
594 requestID.toString());
596 try (OutputStream os = connection.getOutputStream()) {
597 int count = IOUtils.copy(new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)), os);
598 if (LOGGER.isDebugEnabled()) {
599 LOGGER.debug("copied to output, bytes=" + count);
602 connection.connect();
603 responseCode = connection.getResponseCode();
604 // If Connected to PAP then break from the loop and continue
606 if (connection.getResponseCode() > 0 || junit) {
610 LOGGER.debug(XACMLErrorConstants.ERROR_PERMISSIONS+ "PAP Response Code : " + connection.getResponseCode());
613 } catch (Exception e) {
614 // This means that the PAP is not working
619 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR
620 + "PAP connection Error : " + e);
627 LOGGER.debug("connected to the PAP : " + getPAP());
628 LOGGER.debug("--- Response: ---");
629 if(connection != null){
630 Map<String, List<String>> headers = connection.getHeaderFields();
631 for (String key : headers.keySet()) {
632 LOGGER.debug("Header :" + key + " Value: " + headers.get(key));
635 if(responseCode==202){
636 StdPDPPolicy policy = (StdPDPPolicy) new ObjectInputStream(connection.getInputStream()).readObject();
639 } catch (IOException | ClassNotFoundException e) {
640 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
641 throw new PolicyException(
642 XACMLErrorConstants.ERROR_SYSTEM_ERROR
643 + "Decoding the result ", e);