2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
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=========================================================
21 package org.onap.policy.std;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.StringReader;
27 import java.io.UnsupportedEncodingException;
29 import java.net.URLConnection;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Base64;
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.HashMap;
42 import java.util.List;
44 import java.util.Properties;
45 import java.util.UUID;
47 import javax.json.Json;
48 import javax.json.JsonObject;
49 import javax.json.JsonReader;
50 import javax.xml.parsers.DocumentBuilder;
51 import javax.xml.parsers.DocumentBuilderFactory;
53 import org.onap.policy.api.AttributeType;
54 import org.onap.policy.api.ConfigRequestParameters;
55 import org.onap.policy.api.DecisionRequestParameters;
56 import org.onap.policy.api.DecisionResponse;
57 import org.onap.policy.api.DeletePolicyParameters;
58 import org.onap.policy.api.DictionaryParameters;
59 import org.onap.policy.api.DictionaryResponse;
60 import org.onap.policy.api.EventRequestParameters;
61 import org.onap.policy.api.ImportParameters;
62 import org.onap.policy.api.MetricsRequestParameters;
63 import org.onap.policy.api.MetricsResponse;
64 import org.onap.policy.api.NotificationHandler;
65 import org.onap.policy.api.NotificationScheme;
66 import org.onap.policy.api.PDPNotification;
67 import org.onap.policy.api.PolicyChangeResponse;
68 import org.onap.policy.api.PolicyClass;
69 import org.onap.policy.api.PolicyConfig;
70 import org.onap.policy.api.PolicyConfigException;
71 import org.onap.policy.api.PolicyConfigType;
72 import org.onap.policy.api.PolicyDecisionException;
73 import org.onap.policy.api.PolicyEngineException;
74 import org.onap.policy.api.PolicyEventException;
75 import org.onap.policy.api.PolicyException;
76 import org.onap.policy.api.PolicyParameters;
77 import org.onap.policy.api.PolicyResponse;
78 import org.onap.policy.api.PolicyType;
79 import org.onap.policy.api.PushPolicyParameters;
80 import org.onap.policy.common.logging.flexlogger.FlexLogger;
81 import org.onap.policy.common.logging.flexlogger.Logger;
82 import org.onap.policy.models.APIDictionaryResponse;
83 import org.onap.policy.models.APIPolicyConfigResponse;
84 import org.onap.policy.utils.AAFEnvironment;
85 import org.onap.policy.utils.PolicyUtils;
86 import org.onap.policy.xacml.api.XACMLErrorConstants;
87 import org.springframework.core.io.FileSystemResource;
88 import org.springframework.http.HttpEntity;
89 import org.springframework.http.HttpHeaders;
90 import org.springframework.http.HttpMethod;
91 import org.springframework.http.HttpStatus;
92 import org.springframework.http.MediaType;
93 import org.springframework.http.ResponseEntity;
94 import org.springframework.util.LinkedMultiValueMap;
95 import org.springframework.web.client.HttpClientErrorException;
96 import org.springframework.web.client.RestTemplate;
97 import org.xml.sax.InputSource;
99 import com.fasterxml.jackson.core.JsonProcessingException;
100 import com.google.gson.Gson;
101 import com.google.gson.GsonBuilder;
104 * PolicyEngine Implementation class
108 public class StdPolicyEngine {
109 private static final String ERROR_AUTH_GET_PERM = "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to: ";
110 private static final String DEFAULT_NOTIFICATION = "websocket";
112 private String clientEncoding = null;
113 private String contentType = null;
114 private static List<String> pdps = null;
115 private static String environment = null;
116 private static String userName = null;
117 private static String pass = null;
118 private static List<String> encoding = null;
119 private static boolean junit = false;
120 private List<String> pdpDefault = null;
121 private List<String> typeDefault = null;
122 private List<String> notificationType = new ArrayList<>();
123 private List<String> notificationURLList = new ArrayList<>();
124 private NotificationScheme scheme = null;
125 private NotificationHandler handler = null;
126 private AutoClientUEB uebClientThread = null;
127 private Thread registerUEBThread = null;
128 private boolean uebThread = false;
129 private AutoClientDMAAP dmaapClientThread = null;
130 private Thread registerDMAAPThread = null;
131 private boolean dmaapThread = false;
132 private String topic = null;
133 private String apiKey = null;
134 private String apiSecret = null;
136 private static final String UNIQUEID = UUID.randomUUID().toString();
137 private static final Logger LOGGER = FlexLogger.getLogger(StdPolicyConfig.class.getName());
140 * Taking the Property file even if it null.
142 public StdPolicyEngine(String propertyFilePath, String clientKey) throws PolicyEngineException {
143 setProperty(propertyFilePath, clientKey);
147 * Taking the Notification Constructor.
149 public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme, NotificationHandler handler)
150 throws PolicyEngineException {
151 setProperty(propertyFilePath, null);
152 this.scheme = scheme;
153 this.handler = handler;
154 if ((!"ueb".equals(notificationType.get(0))) || (!"dmaap".equals(notificationType.get(0)))) {
155 AutoClientEnd.setAuto(scheme, handler);
157 notification(scheme, handler);
161 * Taking the Notification Constructor.
163 public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme) throws PolicyEngineException {
164 setProperty(propertyFilePath, null);
165 this.scheme = scheme;
170 * sendEvent API Implementation
172 public Collection<PolicyResponse> sendEvent(Map<String, String> eventAttributes, UUID requestID)
173 throws PolicyEventException {
174 return sendEventImpl(eventAttributes, requestID);
178 * sendEvent API Implementation for eventRequestParameters
180 public Collection<PolicyResponse> sendEvent(EventRequestParameters eventRequestParameters)
181 throws PolicyEventException {
182 if (eventRequestParameters == null) {
183 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No event Request Parameters Given. ";
184 LOGGER.error(message);
185 throw new PolicyEventException(message);
187 return sendEventImpl(eventRequestParameters.getEventAttributes(), eventRequestParameters.getRequestID());
191 * getConfig using configRequestParameters Implementation
193 public Collection<PolicyConfig> getConfig(ConfigRequestParameters configRequestParameters)
194 throws PolicyConfigException {
195 return getConfigImpl(configRequestParameters);
199 * listPolicies using configRequestParameters Implementation
201 public Collection<String> listConfig(ConfigRequestParameters listPolicyRequestParameters)
202 throws PolicyConfigException {
203 return listConfigImpl(listPolicyRequestParameters);
207 * getDecision using the decision Attributes.
209 public DecisionResponse getDecision(String onapName, Map<String, String> decisionAttributes, UUID requestID)
210 throws PolicyDecisionException {
211 return getDecisionImpl(onapName, decisionAttributes, requestID);
215 * getDecision Using decisionRequestParameters.
217 public DecisionResponse getDecision(DecisionRequestParameters decisionRequestParameters)
218 throws PolicyDecisionException {
219 if (decisionRequestParameters == null) {
220 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Request Parameters Given. ";
221 LOGGER.error(message);
222 throw new PolicyDecisionException(message);
224 return getDecisionImpl(decisionRequestParameters.getOnapName(),
225 decisionRequestParameters.getDecisionAttributes(), decisionRequestParameters.getRequestID());
229 * getMetrics using metricsRequestParameters
231 public MetricsResponse getMetrics(MetricsRequestParameters parameters) throws PolicyException {
232 return getMetricsImpl(parameters);
235 public MetricsResponse getMetricsImpl(MetricsRequestParameters parameters) throws PolicyException {
236 StdMetricsResponse response = new StdMetricsResponse();
237 String resource = "getMetrics";
239 // Create the Request
241 if (parameters != null) {
242 body = PolicyUtils.objectToJsonString(parameters);
244 } catch (JsonProcessingException e) {
245 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
246 LOGGER.error(message);
247 throw new PolicyException(message, e);
251 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.GET, body, String.class);
253 response.setResponseMessage(result.getBody());
254 response.setResponseCode(result.getStatusCode().value());
255 } catch (PolicyException exception) {
256 if (exception.getCause() != null && exception.getCause() instanceof HttpClientErrorException) {
257 LOGGER.error(exception);
258 HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
259 response.setResponseCode(ex.getRawStatusCode());
260 response.setResponseMessage(exception.getMessage());
263 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR
264 + "Error while processing results. please check logs.";
265 LOGGER.error(message, exception);
266 throw new PolicyException(message, exception);
273 * PushPolicy using pushPolicyParameters.
275 public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws PolicyException {
276 return pushPolicyImpl(pushPolicyParameters);
279 public PolicyChangeResponse pushPolicyImpl(PushPolicyParameters pushPolicyParameters) throws PolicyException {
280 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
281 String resource = "pushPolicy";
285 body = PolicyUtils.objectToJsonString(pushPolicyParameters);
286 } catch (JsonProcessingException e) {
287 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
288 LOGGER.error(message);
289 throw new PolicyException(message, e);
293 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
295 response.setResponseMessage(result.getBody());
296 response.setResponseCode(result.getStatusCode().value());
297 } catch (PolicyException exception) {
298 return processException(exception);
304 * Delete a Policy using deletePolicyParameters
306 public PolicyChangeResponse deletePolicy(DeletePolicyParameters parameters) throws PolicyException {
307 return deletePolicyImpl(parameters);
310 public PolicyChangeResponse deletePolicyImpl(DeletePolicyParameters parameters) throws PolicyException {
311 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
312 String resource = "deletePolicy";
316 body = PolicyUtils.objectToJsonString(parameters);
317 } catch (JsonProcessingException e) {
318 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
319 LOGGER.error(message);
320 throw new PolicyException(message, e);
324 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.DELETE, body, String.class);
326 response.setResponseMessage(result.getBody());
327 response.setResponseCode(result.getStatusCode().value());
328 } catch (PolicyException exception) {
329 return processException(exception);
335 * getDictionaryItem Using dictionaryParameters
337 public DictionaryResponse getDictionaryItem(DictionaryParameters parameters) throws PolicyException {
338 return getDictionaryItemImpl(parameters);
341 public DictionaryResponse getDictionaryItemImpl(DictionaryParameters parameters) throws PolicyException {
342 StdDictionaryResponse response = new StdDictionaryResponse();
343 String resource = "getDictionaryItems";
347 body = PolicyUtils.objectToJsonString(parameters);
348 } catch (JsonProcessingException e) {
349 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
350 LOGGER.error(message);
351 throw new PolicyException(message, e);
355 ResponseEntity<APIDictionaryResponse> result = callNewPDP(resource, HttpMethod.POST, body,
356 APIDictionaryResponse.class);
358 response = dictionaryResult(result.getBody());
359 } catch (Exception exception) {
360 if (exception.getCause().getMessage().contains("401")) {
361 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
362 LOGGER.error(message);
363 response.setResponseMessage(message);
364 response.setResponseCode(401);
367 if (exception.getCause().getMessage().contains("400")) {
368 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
369 response.setResponseMessage(message);
370 response.setResponseCode(400);
373 String message = XACMLErrorConstants.ERROR_PERMISSIONS + "Unable to get valid Response from PDP(s) "
375 LOGGER.error(message, exception);
376 response.setResponseMessage(message);
377 response.setResponseCode(500);
383 @SuppressWarnings("unchecked")
384 private StdDictionaryResponse dictionaryResult(APIDictionaryResponse body) {
385 StdDictionaryResponse response = new StdDictionaryResponse();
386 response.setResponseCode(body.getResponseCode());
387 response.setResponseMessage(body.getResponseMessage());
388 response.setDictionaryData((Map<String, String>) body.getDictionaryData());
389 if (body.getDictionaryJson() != null) {
390 Gson objGson = new GsonBuilder().create();
391 String mapToJson = objGson.toJson(body.getDictionaryJson());
392 JsonReader jsonReader = Json.createReader(new StringReader(mapToJson));
393 JsonObject object = jsonReader.readObject();
395 response.setDictionaryJson(object);
401 * createDictinaryItem Using dictionaryParameters.
403 public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws PolicyException {
404 return createUpdateDictionaryItemImpl(parameters, false);
408 * updateDictinaryItem Using dictionaryParameters.
410 public PolicyChangeResponse updateDictionaryItem(DictionaryParameters parameters) throws PolicyException {
411 return createUpdateDictionaryItemImpl(parameters, true);
414 public PolicyChangeResponse createUpdateDictionaryItemImpl(DictionaryParameters parameters, boolean updateFlag)
415 throws PolicyException {
416 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
417 String resource = "createDictionaryItem";
419 resource = "updateDictionaryItem";
424 body = PolicyUtils.objectToJsonString(parameters);
425 } catch (JsonProcessingException e) {
426 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
427 LOGGER.error(message);
428 throw new PolicyException(message, e);
432 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
434 response.setResponseMessage(result.getBody());
435 response.setResponseCode(result.getStatusCode().value());
436 } catch (PolicyException exception) {
437 return processException(exception);
443 * PolicyEngine Import
445 public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws PolicyException {
446 return policyEngineImportImpl(importParameters);
449 public PolicyChangeResponse policyEngineImportImpl(ImportParameters importParameters) throws PolicyException {
450 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
451 String resource = "policyEngineImport";
452 LinkedMultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
455 String body = PolicyUtils.objectToJsonString(importParameters);
456 parameters.set("importParametersJson", body);
457 parameters.set("file", new FileSystemResource(importParameters.getFilePath()));
458 } catch (Exception e) {
459 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
460 LOGGER.error(message);
461 throw new PolicyException(message, e);
463 contentType = MediaType.MULTIPART_FORM_DATA_VALUE;
466 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.POST, parameters, String.class);
468 response.setResponseMessage(result.getBody());
469 response.setResponseCode(result.getStatusCode().value());
470 } catch (PolicyException exception) {
471 return processException(exception);
479 * createPolicy Using policyParameters.
481 public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws PolicyException {
482 return createUpdatePolicyImpl(policyParameters, false);
486 * updatePolicy using policyParameters.
488 public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws PolicyException {
489 return createUpdatePolicyImpl(policyParameters, true);
492 public PolicyChangeResponse createUpdatePolicyImpl(PolicyParameters policyParameters, boolean updateFlag)
493 throws PolicyException {
494 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
495 String resource = "createPolicy";
497 resource = "updatePolicy";
502 body = PolicyUtils.objectToJsonString(policyParameters);
503 } catch (JsonProcessingException e) {
504 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
505 LOGGER.error(message);
506 throw new PolicyException(message, e);
510 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
512 response.setResponseMessage(result.getBody());
513 response.setResponseCode(result.getStatusCode().value());
514 } catch (PolicyException exception) {
515 return processException(exception);
520 private PolicyChangeResponse processException(PolicyException exception) throws PolicyException {
521 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
522 if (exception.getCause() != null && exception.getCause() instanceof HttpClientErrorException) {
523 LOGGER.error(exception);
524 HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
525 response.setResponseCode(ex.getRawStatusCode());
526 response.setResponseMessage(exception.getMessage());
529 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR
530 + "Error while processing results. please check logs.";
531 LOGGER.error(message, exception);
532 throw new PolicyException(message, exception);
536 public DecisionResponse getDecisionImpl(String onapName, Map<String, String> decisionAttributes, UUID requestID)
537 throws PolicyDecisionException {
538 String resource = "getDecision";
539 StdDecisionResponse response = new StdDecisionResponse();
543 DecisionRequestParameters decisionRequestParameters = new DecisionRequestParameters();
544 decisionRequestParameters.setDecisionAttributes(decisionAttributes);
545 decisionRequestParameters.setOnapName(onapName);
546 decisionRequestParameters.setRequestID(requestID);
547 body = PolicyUtils.objectToJsonString(decisionRequestParameters);
548 } catch (JsonProcessingException e) {
549 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
550 LOGGER.error(message);
551 throw new PolicyDecisionException(message, e);
555 ResponseEntity<StdDecisionResponse> result = callNewPDP(resource, HttpMethod.POST, body,
556 StdDecisionResponse.class);
558 response = result.getBody();
559 } catch (Exception exception) {
560 if (exception.getCause().getMessage().contains("401")) {
561 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
562 LOGGER.error(message);
563 throw new PolicyDecisionException(message, exception);
565 if (exception.getCause().getMessage().contains("400")) {
566 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
567 LOGGER.error(message);
568 throw new PolicyDecisionException(message, exception);
570 String message = XACMLErrorConstants.ERROR_PERMISSIONS + "Unable to get valid Response from PDP(s) "
572 LOGGER.error(message, exception);
573 throw new PolicyDecisionException(message, exception);
578 public Collection<PolicyConfig> getConfigImpl(ConfigRequestParameters configRequestParameters)
579 throws PolicyConfigException {
580 String resource = "getConfig";
581 ArrayList<PolicyConfig> response = new ArrayList<>();
585 body = PolicyUtils.objectToJsonString(configRequestParameters);
586 } catch (JsonProcessingException e) {
587 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
588 LOGGER.error(message);
589 throw new PolicyConfigException(message, e);
593 ResponseEntity<APIPolicyConfigResponse[]> result = callNewPDP(resource, HttpMethod.POST, body,
594 APIPolicyConfigResponse[].class);
596 response = configResult(result.getBody());
597 } catch (Exception exception) {
598 if (exception.getCause().getMessage().contains("401")) {
599 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
600 LOGGER.error(message);
601 throw new PolicyConfigException(message, exception);
603 if (exception.getCause().getMessage().contains("400")) {
604 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
605 LOGGER.error(message);
606 throw new PolicyConfigException(message, exception);
608 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unable to get valid Response from PDP(s) "
610 LOGGER.error(message, exception);
611 throw new PolicyConfigException(message, exception);
616 private ArrayList<PolicyConfig> configResult(APIPolicyConfigResponse[] response) throws PolicyConfigException {
617 ArrayList<PolicyConfig> result = new ArrayList<>();
618 if (response != null && response.length > 0) {
619 for (APIPolicyConfigResponse policyConfigResponse : response) {
620 StdPolicyConfig policyConfig = new StdPolicyConfig();
621 policyConfig.setConfigStatus(policyConfigResponse.getPolicyConfigMessage());
622 policyConfig.setMatchingConditions(policyConfigResponse.getMatchingConditions());
623 policyConfig.setPolicyConfigStatus(policyConfigResponse.getPolicyConfigStatus());
624 policyConfig.setPolicyName(policyConfigResponse.getPolicyName());
625 policyConfig.setPolicyType(policyConfigResponse.getType());
626 policyConfig.setPolicyVersion(policyConfigResponse.getPolicyVersion());
627 policyConfig.setResponseAttributes(policyConfigResponse.getResponseAttributes());
628 setMatches(policyConfig.getMatchingConditions());
629 if (policyConfigResponse.getType() != null) {
631 switch (policyConfigResponse.getType()) {
633 JsonReader jsonReader = Json
634 .createReader(new StringReader(policyConfigResponse.getConfig()));
635 JsonObject object = jsonReader.readObject();
637 policyConfig.setJsonObject(object);
640 policyConfig.setOther(policyConfigResponse.getConfig());
643 Properties props = new Properties();
644 props.putAll(policyConfigResponse.getProperty());
645 policyConfig.setProperties(props);
648 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
649 DocumentBuilder builder;
650 builder = factory.newDocumentBuilder();
651 policyConfig.setDocument(builder
652 .parse(new InputSource(new StringReader(policyConfigResponse.getConfig()))));
655 } catch (Exception e) {
656 LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e);
657 throw new PolicyConfigException(
658 XACMLErrorConstants.ERROR_SCHEMA_INVALID + "Unable to parse the config", e);
661 result.add(policyConfig);
667 private void setMatches(Map<String, String> matchingConditions) {
668 Matches match = new Matches();
669 HashMap<String, String> configAttributes = new HashMap<>();
671 for (String key : matchingConditions.keySet()) {
672 if (key.equalsIgnoreCase("ONAPName")) {
673 match.setOnapName(matchingConditions.get(key));
674 } else if (key.equalsIgnoreCase("ConfigName")) {
675 match.setConfigName(matchingConditions.get(key));
677 configAttributes.put(key, matchingConditions.get(key));
680 if (!configAttributes.isEmpty()) {
681 match.setConfigAttributes(configAttributes);
683 MatchStore.storeMatch(match);
684 } catch (Exception e) {
685 LOGGER.error("StoreMatch failed for Onap:" + match.getOnapName() + " Config: " + match.getConfigName(), e);
690 * Generic Rest Client to call PDP services.
692 private <T> ResponseEntity<T> callNewPDP(String resource, HttpMethod method, Object body, Class<T> responseType)
693 throws PolicyException {
694 RestTemplate restTemplate = new RestTemplate();
695 HttpEntity<?> requestEntity = new HttpEntity<>(body, getHeaders());
696 ResponseEntity<T> result = null;
697 HttpClientErrorException exception = null;
699 while (pdpsCount < pdps.size()) {
701 result = restTemplate.exchange(pdps.get(0) + "/api/" + resource, method, requestEntity, responseType);
702 } catch (HttpClientErrorException e) {
703 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
705 } catch (Exception e) {
706 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
707 exception = new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
709 if (result == null) {
710 Collections.rotate(pdps, -1);
711 Collections.rotate(encoding, -1);
717 if (exception != null && exception.getStatusCode() != null) {
718 if (exception.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
719 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ":" + exception.getStatusCode() + ":"
720 + ERROR_AUTH_GET_PERM + resource;
721 LOGGER.error(message);
722 throw new PolicyException(message, exception);
724 if (exception.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
725 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + ":" + exception.getStatusCode() + ":"
726 + exception.getResponseBodyAsString();
727 LOGGER.error(message);
728 throw new PolicyException(message, exception);
730 if (exception.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
731 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps
733 LOGGER.error(message);
734 throw new PolicyException(message, exception);
736 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + exception.getStatusCode() + ":"
737 + exception.getResponseBodyAsString();
738 LOGGER.error(message);
739 throw new PolicyException(message, exception);
744 private HttpHeaders getHeaders() {
745 HttpHeaders headers = new HttpHeaders();
746 headers.set("ClientAuth", "Basic " + clientEncoding);
747 headers.set("Authorization", "Basic " + encoding.get(0));
748 if (contentType != null) {
749 headers.set("Content-Type", contentType.toString());
751 headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
753 headers.set("Environment", environment);
757 private void setClientEncoding() {
758 Base64.Encoder encoder = Base64.getEncoder();
759 clientEncoding = encoder.encodeToString((userName + ":" + pass).getBytes(StandardCharsets.UTF_8));
762 public Collection<String> listConfigImpl(ConfigRequestParameters listRequestParameters)
763 throws PolicyConfigException {
764 Collection<String> policyList = new ArrayList<>();
766 policyList.add("Policy Name: listConfigTest");
769 Collection<PolicyConfig> policyConfig = getConfigImpl(listRequestParameters);
770 for (PolicyConfig policy : policyConfig) {
771 if (policy.getPolicyConfigMessage() != null && policy.getPolicyConfigMessage().contains("PE300")) {
772 policyList.add(policy.getPolicyConfigMessage());
774 policyList.add("Policy Name: " + policy.getPolicyName());
780 public Collection<PolicyResponse> sendEventImpl(Map<String, String> eventAttributes, UUID requestID)
781 throws PolicyEventException {
782 String resource = "sendEvent";
783 ArrayList<PolicyResponse> response = new ArrayList<PolicyResponse>();
784 String body = new String();
787 // Long way here, can be shortened and will be done.
788 EventRequestParameters eventRequestParameters = new EventRequestParameters();
789 eventRequestParameters.setEventAttributes(eventAttributes);
790 eventRequestParameters.setRequestID(requestID);
791 body = PolicyUtils.objectToJsonString(eventRequestParameters);
792 } catch (JsonProcessingException e) {
793 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
794 LOGGER.error(message);
795 throw new PolicyEventException(message, e);
799 ResponseEntity<StdPolicyResponse[]> result = callNewPDP(resource, HttpMethod.POST, body,
800 StdPolicyResponse[].class);
802 response = eventResult(result.getBody());
803 } catch (Exception exception) {
804 if (exception.getCause().getMessage().contains("401")) {
805 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
806 LOGGER.error(message);
807 throw new PolicyEventException(message, exception);
809 if (exception.getCause().getMessage().contains("400")) {
810 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
811 LOGGER.error(message);
812 throw new PolicyEventException(message, exception);
814 String message = XACMLErrorConstants.ERROR_PERMISSIONS + "Unable to get valid Response from PDP(s) "
816 LOGGER.error(message, exception);
817 throw new PolicyEventException(message, exception);
822 private ArrayList<PolicyResponse> eventResult(StdPolicyResponse[] response) throws PolicyEventException {
823 ArrayList<PolicyResponse> eventResult = new ArrayList<>();
824 if (response != null && response.length > 0) {
825 for (StdPolicyResponse policyConfigResponse : response) {
826 eventResult.add(policyConfigResponse);
832 private void setProperty(String propertyFilePath, String clientKey) throws PolicyEngineException {
833 if (propertyFilePath == null) {
834 throw new PolicyEngineException(
835 XACMLErrorConstants.ERROR_DATA_ISSUE + "Error NO PropertyFile Path provided");
837 // Adding logic for remote Properties file.
838 Properties prop = new Properties();
839 if (propertyFilePath.startsWith("http")) {
842 configURL = new URL(propertyFilePath);
843 URLConnection connection = null;
844 connection = configURL.openConnection();
845 prop.load(connection.getInputStream());
846 } catch (IOException e) {
847 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
848 throw new PolicyEngineException(
849 XACMLErrorConstants.ERROR_DATA_ISSUE + "Maformed property URL " + e.getMessage());
852 Path file = Paths.get(propertyFilePath);
853 if (Files.notExists(file)) {
854 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE
855 + "File doesn't exist in the specified Path " + file.toString());
857 if (file.toString().endsWith(".properties")) {
859 prop = new Properties();
861 in = new FileInputStream(file.toFile());
863 } catch (IOException e) {
864 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
865 throw new PolicyEngineException(
866 XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Cannot Load the Properties file", e);
869 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file " + propertyFilePath);
870 throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file");
873 // UEB and DMAAP Settings
874 String checkType = prop.getProperty("NOTIFICATION_TYPE");
875 String serverList = prop.getProperty("NOTIFICATION_SERVERS");
876 topic = prop.getProperty("NOTIFICATION_TOPIC");
877 apiKey = prop.getProperty("UEB_API_KEY");
878 apiSecret = prop.getProperty("UEB_API_SECRET");
880 if (checkType == null) {
881 notificationType.add(DEFAULT_NOTIFICATION);
883 "Properties file doesn't have the NOTIFICATION_TYPE parameter system will use defualt websockets");
885 checkType = checkType.trim();
886 if (checkType.contains(",")) {
887 typeDefault = new ArrayList<>(Arrays.asList(prop.getProperty("NOTIFICATION_TYPE").split(",")));
888 notificationType = typeDefault;
890 notificationType = new ArrayList<>();
891 notificationType.add(checkType);
894 if (serverList == null) {
895 notificationType.clear();
896 notificationType.add(DEFAULT_NOTIFICATION);
898 "Properties file doesn't have the NOTIFICATION_SERVERS parameter system will use defualt websockets");
900 serverList = serverList.trim();
901 if (serverList.contains(",")) {
902 notificationURLList = new ArrayList<String>(Arrays.asList(serverList.split(",")));
904 notificationURLList = new ArrayList<>();
905 notificationURLList.add(serverList);
910 topic = topic.trim();
912 LOGGER.error("Properties file doesn't have the NOTIFICATION_TOPIC parameter.");
915 // Client ID Authorization Settings.
916 String clientID = prop.getProperty("CLIENT_ID");
917 if (clientKey == null) {
918 clientKey = prop.getProperty("CLIENT_KEY");
920 clientKey = PolicyUtils.decode(clientKey);
921 } catch (UnsupportedEncodingException | IllegalArgumentException e) {
922 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS
923 + " Cannot Decode the given Password Proceeding with given Password!!", e);
926 if (clientID == null || clientKey == null || clientID.isEmpty() || clientKey.isEmpty()) {
927 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS
928 + " Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
929 throw new PolicyEngineException(XACMLErrorConstants.ERROR_PERMISSIONS
930 + " Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
932 setClientId(clientID.trim());
933 setClientKey(clientKey.trim());
935 setEnvironment(prop);
936 // Initializing the values.
938 // Check the Keys for PDP_URLs
939 Collection<Object> unsorted = prop.keySet();
940 @SuppressWarnings({ "rawtypes", "unchecked" })
941 List<String> sorted = new ArrayList(unsorted);
942 Collections.sort(sorted);
943 for (String propKey : sorted) {
944 if (propKey.startsWith("PDP_URL")) {
945 String checkVal = prop.getProperty(propKey);
946 if (checkVal == null) {
947 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE
948 + "Properties file doesn't have the PDP_URL parameter");
950 if (checkVal.contains(";")) {
951 pdpDefault = new ArrayList<>(Arrays.asList(checkVal.split("\\s*;\\s*")));
953 while (pdpCount < pdpDefault.size()) {
954 String pdpVal = pdpDefault.get(pdpCount);
955 readPDPParam(pdpVal);
959 readPDPParam(checkVal);
963 if (pdps == null || pdps.isEmpty()) {
964 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
965 throw new PolicyEngineException(
966 XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
968 // Get JUNIT property from properties file when running tests
973 private static void checkJunit(Properties prop) {
974 String junitFlag = prop.getProperty("JUNIT");
975 if (junitFlag == null || junitFlag.isEmpty()) {
976 LOGGER.info("No JUNIT property provided, this will not be executed as a test.");
978 if (junitFlag.equalsIgnoreCase("test")) {
979 StdPolicyEngine.junit = true;
981 StdPolicyEngine.junit = false;
986 private static void init() {
987 pdps = new ArrayList<>();
988 encoding = new ArrayList<>();
991 private static void setEnvironment(Properties prop) {
992 environment = prop.getProperty("ENVIRONMENT", AAFEnvironment.DEVL.toString());
993 if (environment.equalsIgnoreCase(AAFEnvironment.TEST.toString())) {
994 environment = AAFEnvironment.TEST.toString();
995 } else if (environment.equalsIgnoreCase(AAFEnvironment.PROD.toString())) {
996 environment = AAFEnvironment.PROD.toString();
998 environment = AAFEnvironment.DEVL.toString();
1002 private static void setClientId(String clientID) {
1003 userName = clientID;
1007 * Read the PDP_URL parameter
1009 private void readPDPParam(String pdpVal) throws PolicyEngineException {
1010 if (pdpVal.contains(",")) {
1011 List<String> pdpValues = new ArrayList<String>(Arrays.asList(pdpVal.split("\\s*,\\s*")));
1012 if (pdpValues.size() == 3) {
1014 pdps.add(pdpValues.get(0));
1015 // 1:2 will be UserID:Password
1016 String userID = pdpValues.get(1);
1017 String pass = pdpValues.get(2);
1018 Base64.Encoder encoder = Base64.getEncoder();
1019 encoding.add(encoder.encodeToString((userID + ":" + pass).getBytes(StandardCharsets.UTF_8)));
1021 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + pdpValues);
1022 throw new PolicyEngineException(
1023 XACMLErrorConstants.ERROR_DATA_ISSUE + "No enough Credentials to send Request. " + pdpValues);
1027 XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values: " + pdpVal);
1028 throw new PolicyEngineException(
1029 XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values.");
1034 * Allowing changes to the scheme and Handler.
1036 public void notification(NotificationScheme scheme, NotificationHandler handler) {
1037 this.scheme = scheme;
1038 this.handler = handler;
1039 LOGGER.debug("Scheme is : " + scheme.toString());
1040 LOGGER.debug("Handler is : " + handler.getClass().getName());
1042 if (notificationType.get(0).equals("ueb")) {
1043 if (this.uebThread) {
1044 AutoClientUEB.setAuto(scheme, handler);
1045 this.uebThread = registerUEBThread.isAlive();
1047 } else if (notificationType.get(0).equals("dmaap")) {
1048 if (this.dmaapThread) {
1049 AutoClientDMAAP.setAuto(scheme, handler);
1050 this.dmaapThread = registerDMAAPThread.isAlive();
1053 AutoClientEnd.setAuto(scheme, handler);
1061 if (notificationType.get(0).equals("ueb") && !this.uebThread) {
1062 this.uebClientThread = new AutoClientUEB(pdps.get(0), notificationURLList, apiKey, apiSecret);
1063 AutoClientUEB.setAuto(scheme, handler);
1064 this.registerUEBThread = new Thread(this.uebClientThread);
1065 this.registerUEBThread.start();
1066 this.uebThread = true;
1067 } else if (notificationType.get(0).equals("dmaap") && !this.dmaapThread) {
1068 this.dmaapClientThread = new AutoClientDMAAP(notificationURLList, topic, userName, pass);
1069 AutoClientDMAAP.setAuto(scheme, handler);
1070 this.registerDMAAPThread = new Thread(this.dmaapClientThread);
1071 this.registerDMAAPThread.start();
1072 this.dmaapThread = true;
1074 if (pdps.get(0) != null) {
1075 if (AutoClientEnd.getURL() == null) {
1076 AutoClientEnd.start(pdps.get(0));
1078 AutoClientEnd.stop();
1079 AutoClientEnd.start(pdps.get(0));
1087 * Gets the Notification if one exists. Used only for Manual Polling purposes.
1089 public PDPNotification getNotification() {
1090 // Check if there is proper scheme..
1091 PDPNotification notification = null;
1092 if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)
1093 || this.scheme.equals(NotificationScheme.MANUAL_NOTIFICATIONS)) {
1094 if (notificationType.get(0).equals("ueb")) {
1095 ManualClientEndUEB.start(pdps.get(0), notificationURLList, UNIQUEID);
1096 notification = ManualClientEndUEB.result(scheme);
1097 } else if (notificationType.get(0).equals("dmaap")) {
1098 ManualClientEndDMAAP.start(notificationURLList, topic, UNIQUEID, userName, pass);
1099 notification = ManualClientEndDMAAP.result(scheme);
1101 ManualClientEnd.start(pdps.get(0));
1102 LOGGER.debug("manual notification requested.. : " + scheme.toString());
1103 notification = ManualClientEnd.result(scheme);
1105 if (notification == null) {
1106 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Notification yet..");
1109 return notification;
1117 * Setting the Scheme.
1119 public void setScheme(NotificationScheme scheme) {
1120 this.scheme = scheme;
1121 if (notificationType.get(0).equals("ueb")) {
1122 AutoClientUEB.setScheme(this.scheme);
1123 if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)) {
1124 ManualClientEndUEB.createTopic(pdps.get(0), UNIQUEID, notificationURLList);
1126 } else if (notificationType.get(0).equals("dmaap")) {
1127 AutoClientDMAAP.setScheme(this.scheme);
1128 if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)) {
1129 ManualClientEndDMAAP.createTopic(topic, UNIQUEID, notificationURLList, userName, pass);
1132 AutoClientEnd.setScheme(this.scheme);
1137 * Returns the Scheme
1139 public NotificationScheme getScheme() {
1144 * Returns the NotificationHandler
1146 public NotificationHandler getNotificationHandler() {
1147 return this.handler;
1151 * Stop the Notification Service if its running.
1153 public void stopNotification() {
1154 if (this.scheme != null && this.handler != null) {
1155 if (this.scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)
1156 || this.scheme.equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
1157 LOGGER.info("Clear Notification called.. ");
1158 if (notificationType.get(0).equals("ueb")) {
1159 this.uebClientThread.terminate();
1160 this.uebThread = false;
1161 } else if (notificationType.get(0).equals("dmaap")) {
1162 this.dmaapClientThread.terminate();
1163 this.dmaapThread = false;
1165 AutoClientEnd.stop();
1172 * Push a policy to the PDP API implementation
1174 public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID)
1175 throws PolicyException {
1176 PushPolicyParameters pushPolicyParameters = new PushPolicyParameters();
1177 if (policyScope == null || policyScope.trim().isEmpty()) {
1178 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1179 LOGGER.error(message);
1180 throw new PolicyException(message);
1182 if (policyName == null || policyName.trim().isEmpty()) {
1183 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1184 LOGGER.error(message);
1185 throw new PolicyException(message);
1187 pushPolicyParameters.setPolicyName(policyScope + "." + policyName);
1188 pushPolicyParameters.setPolicyType(policyType);
1189 pushPolicyParameters.setPdpGroup(pdpGroup);
1190 pushPolicyParameters.setRequestID(requestID);
1191 return pushPolicyImpl(pushPolicyParameters).getResponseMessage();
1194 public String createUpdateConfigPolicy(String policyName, String policyDescription, String onapName,
1195 String configName, Map<String, String> configAttributes, String configType, String body, String policyScope,
1196 UUID requestID, String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag)
1197 throws PolicyException {
1198 return createUpdateConfigPolicyImpl(policyName, policyDescription, onapName, configName, configAttributes,
1199 configType, body, policyScope, requestID, riskLevel, riskType, guard, ttlDate, updateFlag);
1203 * Create Config Policy API Implementation
1205 public String createUpdateConfigPolicyImpl(String policyName, String policyDescription, String onapName,
1206 String configName, Map<String, String> configAttributes, String configType, String body, String policyScope,
1207 UUID requestID, String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag)
1208 throws PolicyException {
1209 PolicyParameters policyParameters = new PolicyParameters();
1210 policyParameters.setPolicyClass(PolicyClass.Config);
1211 policyParameters.setPolicyConfigType(PolicyConfigType.Base);
1212 if (policyScope == null || policyScope.trim().isEmpty()) {
1213 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1214 LOGGER.error(message);
1215 throw new PolicyException(message);
1217 if (policyName == null || policyName.trim().isEmpty()) {
1218 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1219 LOGGER.error(message);
1220 throw new PolicyException(message);
1222 policyParameters.setPolicyName(policyScope + "." + policyName);
1223 policyParameters.setPolicyDescription(policyDescription);
1224 policyParameters.setOnapName(onapName);
1225 policyParameters.setConfigName(configName);
1226 Map<AttributeType, Map<String, String>> attributes = new HashMap<AttributeType, Map<String, String>>();
1227 attributes.put(AttributeType.MATCHING, configAttributes);
1228 policyParameters.setAttributes(attributes);
1229 policyParameters.setConfigBodyType(PolicyType.valueOf(configType));
1230 policyParameters.setConfigBody(body);
1231 policyParameters.setRequestID(requestID);
1232 policyParameters.setRiskLevel(riskLevel);
1233 policyParameters.setRiskType(riskType);
1234 policyParameters.setGuard(Boolean.parseBoolean(guard));
1236 policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
1237 } catch (ParseException e) {
1238 LOGGER.warn("Error Parsing date given " + ttlDate);
1239 policyParameters.setTtlDate(null);
1241 return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
1244 public String createUpdateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope,
1245 UUID requestID, String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag)
1246 throws PolicyException {
1247 return createUpdateConfigFirewallPolicyImpl(policyName, firewallJson, policyScope, requestID, riskLevel,
1248 riskType, guard, ttlDate, updateFlag);
1252 * Create Update Config Firewall Policy API implementation
1254 public String createUpdateConfigFirewallPolicyImpl(String policyName, JsonObject firewallJson, String policyScope,
1255 UUID requestID, String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag)
1256 throws PolicyException {
1257 PolicyParameters policyParameters = new PolicyParameters();
1258 policyParameters.setPolicyClass(PolicyClass.Config);
1259 policyParameters.setPolicyConfigType(PolicyConfigType.Firewall);
1260 if (policyScope == null || policyScope.trim().isEmpty()) {
1261 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1262 LOGGER.error(message);
1263 throw new PolicyException(message);
1265 if (policyName == null || policyName.trim().isEmpty()) {
1266 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1267 LOGGER.error(message);
1268 throw new PolicyException(message);
1270 policyParameters.setPolicyName(policyScope + "." + policyName);
1271 policyParameters.setConfigBody(firewallJson.toString());
1272 policyParameters.setRequestID(requestID);
1273 policyParameters.setRiskLevel(riskLevel);
1274 policyParameters.setRiskType(riskType);
1275 policyParameters.setGuard(Boolean.parseBoolean(guard));
1277 policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
1278 } catch (NullPointerException | ParseException e) {
1279 LOGGER.warn("Error Parsing date given " + ttlDate);
1280 policyParameters.setTtlDate(null);
1282 return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
1285 public void setClientKey(String clientKey) {
1286 if (clientKey != null && !clientKey.isEmpty()) {
1287 StdPolicyEngine.pass = clientKey;
1288 setClientEncoding();
1293 * Get the Environment.
1295 public static String getEnvironment() {
1300 * Rotate the PDP list upon WEBsocket Failures
1302 public static void rotatePDPList() {
1303 Collections.rotate(pdps, -1);
1304 Collections.rotate(encoding, -1);
1308 * Get the latest PDP
1310 public static String getPDPURL() {