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=========================================================
22 package org.onap.policy.std;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.StringReader;
28 import java.io.UnsupportedEncodingException;
30 import java.net.URLConnection;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.text.ParseException;
36 import java.text.SimpleDateFormat;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Base64;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.List;
45 import java.util.Properties;
46 import java.util.UUID;
48 import javax.json.Json;
49 import javax.json.JsonObject;
50 import javax.json.JsonReader;
51 import javax.xml.parsers.DocumentBuilder;
52 import javax.xml.parsers.DocumentBuilderFactory;
54 import org.onap.policy.api.AttributeType;
55 import org.onap.policy.api.ConfigRequestParameters;
56 import org.onap.policy.api.DecisionRequestParameters;
57 import org.onap.policy.api.DecisionResponse;
58 import org.onap.policy.api.DeletePolicyParameters;
59 import org.onap.policy.api.DictionaryParameters;
60 import org.onap.policy.api.DictionaryResponse;
61 import org.onap.policy.api.EventRequestParameters;
62 import org.onap.policy.api.ImportParameters;
63 import org.onap.policy.api.MetricsRequestParameters;
64 import org.onap.policy.api.MetricsResponse;
65 import org.onap.policy.api.NotificationHandler;
66 import org.onap.policy.api.NotificationScheme;
67 import org.onap.policy.api.PDPNotification;
68 import org.onap.policy.api.PolicyChangeResponse;
69 import org.onap.policy.api.PolicyClass;
70 import org.onap.policy.api.PolicyConfig;
71 import org.onap.policy.api.PolicyConfigException;
72 import org.onap.policy.api.PolicyConfigType;
73 import org.onap.policy.api.PolicyDecisionException;
74 import org.onap.policy.api.PolicyEngineException;
75 import org.onap.policy.api.PolicyEventException;
76 import org.onap.policy.api.PolicyException;
77 import org.onap.policy.api.PolicyParameters;
78 import org.onap.policy.api.PolicyResponse;
79 import org.onap.policy.api.PolicyType;
80 import org.onap.policy.api.PushPolicyParameters;
81 import org.onap.policy.common.logging.flexlogger.FlexLogger;
82 import org.onap.policy.common.logging.flexlogger.Logger;
83 import org.onap.policy.models.APIDictionaryResponse;
84 import org.onap.policy.models.APIPolicyConfigResponse;
85 import org.onap.policy.utils.AAFEnvironment;
86 import org.onap.policy.utils.PolicyUtils;
87 import org.onap.policy.xacml.api.XACMLErrorConstants;
88 import org.springframework.core.io.FileSystemResource;
89 import org.springframework.http.HttpEntity;
90 import org.springframework.http.HttpHeaders;
91 import org.springframework.http.HttpMethod;
92 import org.springframework.http.HttpStatus;
93 import org.springframework.http.MediaType;
94 import org.springframework.http.ResponseEntity;
95 import org.springframework.util.LinkedMultiValueMap;
96 import org.springframework.web.client.HttpClientErrorException;
97 import org.springframework.web.client.RestTemplate;
98 import org.xml.sax.InputSource;
100 import com.fasterxml.jackson.core.JsonProcessingException;
101 import com.google.gson.Gson;
102 import com.google.gson.GsonBuilder;
105 * PolicyEngine Implementation class
109 public class StdPolicyEngine {
110 private static final String ERROR_AUTH_GET_PERM = "You are not allowed to Make this Request. Please contact PolicyAdmin to give access to: ";
111 private static final String DEFAULT_NOTIFICATION = "websocket";
113 private String propertyFilePath = null;
114 private String clientEncoding = null;
115 private String contentType = null;
116 private static List<String> pdps = null;
117 private static String environment= null;
118 private static String userName = null;
119 private static String pass = null;
120 private static List<String> encoding = null;
121 private static boolean junit = false;
122 private List<String> pdpDefault = null;
123 private List<String> typeDefault = null;
124 private List<String> notificationType = new ArrayList<String>();
125 private List<String> notificationURLList = new ArrayList<String>();
126 private NotificationScheme scheme = null;
127 private NotificationHandler handler = null;
128 private AutoClientUEB uebClientThread = null;
129 private Thread registerUEBThread = null;
130 private boolean uebThread = false;
131 private AutoClientDMAAP dmaapClientThread = null;
132 private Thread registerDMAAPThread = null;
133 private boolean dmaapThread = false;
134 private String topic = null;
135 private String apiKey = null;
136 private String apiSecret = null;
138 private static final String UNIQUEID = UUID.randomUUID ().toString ();
139 private static final Logger LOGGER = FlexLogger.getLogger(StdPolicyConfig.class.getName());
142 * Taking the Property file even if it null.
144 public StdPolicyEngine(String propertyFilePath, String clientKey) throws PolicyEngineException {
145 setProperty(propertyFilePath, clientKey);
149 * Taking the Notification Constructor.
151 public StdPolicyEngine(String propertyFilePath,
152 NotificationScheme scheme,
153 NotificationHandler handler) throws PolicyEngineException {
154 setProperty(propertyFilePath, null);
155 this.scheme = scheme;
156 this.handler = handler;
157 if ((!"ueb".equals(notificationType.get(0)))||(!"dmaap".equals(notificationType.get(0)))){
158 AutoClientEnd.setAuto(scheme, handler);
160 notification(scheme, handler);
164 * Taking the Notification Constructor.
166 public StdPolicyEngine(String propertyFilePath, NotificationScheme scheme) throws PolicyEngineException {
167 setProperty(propertyFilePath, null);
168 this.scheme = scheme;
173 * sendEvent API Implementation
175 public Collection<PolicyResponse> sendEvent(Map<String, String> eventAttributes, UUID requestID) throws PolicyEventException {
176 return sendEventImpl(eventAttributes, requestID);
180 * sendEvent API Implementation for eventRequestParameters
182 public Collection<PolicyResponse> sendEvent(EventRequestParameters eventRequestParameters) throws PolicyEventException{
183 if(eventRequestParameters==null){
184 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No event Request Parameters Given. ";
185 LOGGER.error(message);
186 throw new PolicyEventException(message);
188 return sendEventImpl(eventRequestParameters.getEventAttributes(), eventRequestParameters.getRequestID());
192 * getConfig using configRequestParameters Implementation
194 public Collection<PolicyConfig> getConfig(ConfigRequestParameters configRequestParameters) throws PolicyConfigException{
195 return getConfigImpl(configRequestParameters);
199 * listPolicies using configRequestParameters Implementation
201 public Collection<String> listConfig(ConfigRequestParameters listPolicyRequestParameters) throws PolicyConfigException{
202 return listConfigImpl(listPolicyRequestParameters);
206 * getDecision using the decision Attributes.
208 public DecisionResponse getDecision(String onapComponentName, Map<String, String> decisionAttributes, UUID requestID) throws PolicyDecisionException {
209 return getDecisionImpl(onapComponentName, decisionAttributes, requestID);
213 * getDecision Using decisionRequestParameters.
215 public DecisionResponse getDecision(DecisionRequestParameters decisionRequestParameters) throws PolicyDecisionException{
216 if(decisionRequestParameters==null){
217 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Request Parameters Given. ";
218 LOGGER.error(message);
219 throw new PolicyDecisionException(message);
221 return getDecisionImpl(decisionRequestParameters.getONAPComponentName(), decisionRequestParameters.getDecisionAttributes(), decisionRequestParameters.getRequestID());
225 * getMetrics using metricsRequestParameters
227 public MetricsResponse getMetrics(MetricsRequestParameters parameters) throws PolicyException{
228 return getMetricsImpl(parameters);
231 public MetricsResponse getMetricsImpl(MetricsRequestParameters parameters) throws PolicyException{
232 StdMetricsResponse response = new StdMetricsResponse();
233 String resource = "getMetrics";
234 String body = new String();
236 // Create the Request
238 if (parameters!=null) {
239 body = PolicyUtils.objectToJsonString(parameters);
241 } catch (JsonProcessingException e) {
242 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
243 LOGGER.error(message);
244 throw new PolicyException(message, e);
248 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.GET, body, String.class);
250 response.setResponseMessage(result.getBody());
251 response.setResponseCode(result.getStatusCode().value());
252 } catch (PolicyException exception) {
253 if(exception.getCause()!=null && exception.getCause() instanceof HttpClientErrorException){
254 LOGGER.error(exception);
255 HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
256 response.setResponseCode(ex.getRawStatusCode());
257 response.setResponseMessage(exception.getMessage());
260 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR+ "Error while processing results. please check logs.";
261 LOGGER.error(message, exception);
262 throw new PolicyException(message, exception);
269 * PushPolicy using pushPolicyParameters.
271 public PolicyChangeResponse pushPolicy(PushPolicyParameters pushPolicyParameters) throws PolicyException{
272 return pushPolicyImpl(pushPolicyParameters);
275 public PolicyChangeResponse pushPolicyImpl(PushPolicyParameters pushPolicyParameters) throws PolicyException{
276 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
277 String resource= "pushPolicy";
278 String body = new String();
281 body = PolicyUtils.objectToJsonString(pushPolicyParameters);
282 } catch (JsonProcessingException e) {
283 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
284 LOGGER.error(message);
285 throw new PolicyException(message, e);
289 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
291 response.setResponseMessage(result.getBody());
292 response.setResponseCode(result.getStatusCode().value());
293 } catch (PolicyException exception) {
294 return processException(exception);
300 * Delete a Policy using deletePolicyParameters
302 public PolicyChangeResponse deletePolicy(DeletePolicyParameters parameters) throws PolicyException {
303 return deletePolicyImpl(parameters);
306 public PolicyChangeResponse deletePolicyImpl(DeletePolicyParameters parameters) throws PolicyException {
307 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
308 String resource= "deletePolicy";
309 String body = new String();
312 body = PolicyUtils.objectToJsonString(parameters);
313 } catch (JsonProcessingException e) {
314 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
315 LOGGER.error(message);
316 throw new PolicyException(message, e);
320 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.DELETE, body, String.class);
322 response.setResponseMessage(result.getBody());
323 response.setResponseCode(result.getStatusCode().value());
324 } catch (PolicyException exception) {
325 return processException(exception);
331 * getDictionaryItem Using dictionaryParameters
333 public DictionaryResponse getDictionaryItem(DictionaryParameters parameters) throws PolicyException {
334 return getDictionaryItemImpl(parameters);
337 public DictionaryResponse getDictionaryItemImpl(DictionaryParameters parameters) throws PolicyException{
338 StdDictionaryResponse response = new StdDictionaryResponse();
339 String resource="getDictionaryItems";
343 body = PolicyUtils.objectToJsonString(parameters);
344 } catch (JsonProcessingException e) {
345 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
346 LOGGER.error(message);
347 throw new PolicyException(message, e);
351 ResponseEntity<APIDictionaryResponse> result = callNewPDP(resource, HttpMethod.POST, body, APIDictionaryResponse.class);
353 response = dictionaryResult(result.getBody());
354 } catch (Exception exception) {
355 if(exception.getCause().getMessage().contains("401")){
356 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
357 LOGGER.error(message);
358 response.setResponseMessage(message);
359 response.setResponseCode(401);
361 }if(exception.getCause().getMessage().contains("400")){
362 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
363 response.setResponseMessage(message);
364 response.setResponseCode(400);
367 String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from PDP(s) " + pdps;
368 LOGGER.error(message, exception);
369 response.setResponseMessage(message);
370 response.setResponseCode(500);
376 @SuppressWarnings("unchecked")
377 private StdDictionaryResponse dictionaryResult(APIDictionaryResponse body) {
378 StdDictionaryResponse response = new StdDictionaryResponse();
379 response.setResponseCode(body.getResponseCode());
380 response.setResponseMessage(body.getResponseMessage());
381 response.setDictionaryData((Map<String, String>) body.getDictionaryData());
382 if(body.getDictionaryJson()!=null){
383 Gson objGson = new GsonBuilder().create();
384 String mapToJson = objGson.toJson(body.getDictionaryJson());
385 JsonReader jsonReader = Json.createReader(new StringReader(mapToJson));
386 JsonObject object = jsonReader.readObject();
388 response.setDictionaryJson(object);
394 * createDictinaryItem Using dictionaryParameters.
396 public PolicyChangeResponse createDictionaryItem(DictionaryParameters parameters) throws PolicyException{
397 return createUpdateDictionaryItemImpl(parameters, false);
401 * updateDictinaryItem Using dictionaryParameters.
403 public PolicyChangeResponse updateDictionaryItem(DictionaryParameters parameters) throws PolicyException{
404 return createUpdateDictionaryItemImpl(parameters, true);
407 public PolicyChangeResponse createUpdateDictionaryItemImpl(DictionaryParameters parameters, boolean updateFlag) throws PolicyException{
408 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
409 String resource = "createDictionaryItem";
411 resource = "updateDictionaryItem";
413 String body = new String();
416 body = PolicyUtils.objectToJsonString(parameters);
417 } catch (JsonProcessingException e) {
418 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
419 LOGGER.error(message);
420 throw new PolicyException(message, e);
424 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
426 response.setResponseMessage(result.getBody());
427 response.setResponseCode(result.getStatusCode().value());
428 } catch (PolicyException exception) {
429 return processException(exception);
435 * PolicyEngine Import
437 public PolicyChangeResponse policyEngineImport(ImportParameters importParameters) throws PolicyException {
438 return policyEngineImportImpl(importParameters);
441 public PolicyChangeResponse policyEngineImportImpl(ImportParameters importParameters) throws PolicyException {
442 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
443 String resource= "policyEngineImport";
444 LinkedMultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
447 String body = PolicyUtils.objectToJsonString(importParameters);
448 parameters.set("importParametersJson", body);
449 parameters.set("file", new FileSystemResource(importParameters.getFilePath()));
450 } catch (Exception e) {
451 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
452 LOGGER.error(message);
453 throw new PolicyException(message, e);
455 contentType = MediaType.MULTIPART_FORM_DATA_VALUE;
458 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.POST, parameters, String.class);
460 response.setResponseMessage(result.getBody());
461 response.setResponseCode(result.getStatusCode().value());
462 } catch (PolicyException exception) {
463 return processException(exception);
471 * createPolicy Using policyParameters.
473 public PolicyChangeResponse createPolicy(PolicyParameters policyParameters) throws PolicyException{
474 return createUpdatePolicyImpl(policyParameters, false);
478 * updatePolicy using policyParameters.
480 public PolicyChangeResponse updatePolicy(PolicyParameters policyParameters) throws PolicyException{
481 return createUpdatePolicyImpl(policyParameters, true);
484 public PolicyChangeResponse createUpdatePolicyImpl(PolicyParameters policyParameters, boolean updateFlag) throws PolicyException{
485 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
486 String resource= "createPolicy";
488 resource="updatePolicy";
490 String body = new String();
493 body = PolicyUtils.objectToJsonString(policyParameters);
494 } catch (JsonProcessingException e) {
495 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
496 LOGGER.error(message);
497 throw new PolicyException(message, e);
501 ResponseEntity<String> result = callNewPDP(resource, HttpMethod.PUT, body, String.class);
503 response.setResponseMessage(result.getBody());
504 response.setResponseCode(result.getStatusCode().value());
505 } catch (PolicyException exception) {
506 return processException(exception);
511 private PolicyChangeResponse processException(PolicyException exception) throws PolicyException {
512 StdPolicyChangeResponse response = new StdPolicyChangeResponse();
513 if(exception.getCause()!=null && exception.getCause() instanceof HttpClientErrorException){
514 LOGGER.error(exception);
515 HttpClientErrorException ex = (HttpClientErrorException) exception.getCause();
516 response.setResponseCode(ex.getRawStatusCode());
517 response.setResponseMessage(exception.getMessage());
520 String message = XACMLErrorConstants.ERROR_SYSTEM_ERROR+ "Error while processing results. please check logs.";
521 LOGGER.error(message, exception);
522 throw new PolicyException(message, exception);
526 public DecisionResponse getDecisionImpl(String onapComponentName,
527 Map<String, String> decisionAttributes,
528 UUID requestID) throws PolicyDecisionException {
529 String resource= "getDecision";
530 StdDecisionResponse response = new StdDecisionResponse();
531 String body = new String();
534 DecisionRequestParameters decisionRequestParameters = new DecisionRequestParameters();
535 decisionRequestParameters.setDecisionAttributes(decisionAttributes);
536 decisionRequestParameters.setONAPComponentName(onapComponentName);
537 decisionRequestParameters.setRequestID(requestID);
538 body = PolicyUtils.objectToJsonString(decisionRequestParameters);
539 } catch (JsonProcessingException e) {
540 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
541 LOGGER.error(message);
542 throw new PolicyDecisionException(message, e);
546 ResponseEntity<StdDecisionResponse> result = callNewPDP(resource, HttpMethod.POST, body, StdDecisionResponse.class);
548 response = result.getBody();
549 } catch (Exception exception) {
550 if(exception.getCause().getMessage().contains("401")){
551 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
552 LOGGER.error(message);
553 throw new PolicyDecisionException(message, exception);
554 }if(exception.getCause().getMessage().contains("400")){
555 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
556 LOGGER.error(message);
557 throw new PolicyDecisionException(message, exception);
559 String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from PDP(s) " + pdps;
560 LOGGER.error(message, exception);
561 throw new PolicyDecisionException(message, exception);
566 public Collection<PolicyConfig> getConfigImpl(ConfigRequestParameters configRequestParameters) throws PolicyConfigException{
567 String resource= "getConfig";
568 ArrayList<PolicyConfig> response = new ArrayList<>();
569 String body = new String();
572 body = PolicyUtils.objectToJsonString(configRequestParameters);
573 } catch (JsonProcessingException e) {
574 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
575 LOGGER.error(message);
576 throw new PolicyConfigException(message, e);
580 ResponseEntity<APIPolicyConfigResponse[]> result = callNewPDP(resource, HttpMethod.POST, body, APIPolicyConfigResponse[].class);
582 response = configResult(result.getBody());
583 } catch (Exception exception) {
584 if(exception.getCause().getMessage().contains("401")){
585 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
586 LOGGER.error(message);
587 throw new PolicyConfigException(message, exception);
588 }if(exception.getCause().getMessage().contains("400")){
589 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
590 LOGGER.error(message);
591 throw new PolicyConfigException(message, exception);
593 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW+ "Unable to get valid Response from PDP(s) " + pdps;
594 LOGGER.error(message, exception);
595 throw new PolicyConfigException(message, exception);
600 private ArrayList<PolicyConfig> configResult(APIPolicyConfigResponse[] response) throws PolicyConfigException {
601 ArrayList<PolicyConfig> result = new ArrayList<>();
602 if(response!=null && response.length>0){
603 for(APIPolicyConfigResponse policyConfigResponse: response){
604 StdPolicyConfig policyConfig = new StdPolicyConfig();
605 policyConfig.setConfigStatus(policyConfigResponse.getPolicyConfigMessage());
606 policyConfig.setMatchingConditions(policyConfigResponse.getMatchingConditions());
607 policyConfig.setPolicyConfigStatus(policyConfigResponse.getPolicyConfigStatus());
608 policyConfig.setPolicyName(policyConfigResponse.getPolicyName());
609 policyConfig.setPolicyType(policyConfigResponse.getType());
610 policyConfig.setPolicyVersion(policyConfigResponse.getPolicyVersion());
611 policyConfig.setResponseAttributes(policyConfigResponse.getResponseAttributes());
612 setMatches(policyConfig.getMatchingConditions());
613 if(policyConfigResponse.getType()!=null){
615 switch (policyConfigResponse.getType()) {
617 JsonReader jsonReader = Json.createReader(new StringReader(policyConfigResponse.getConfig()));
618 JsonObject object = jsonReader.readObject();
620 policyConfig.setJsonObject(object);
623 policyConfig.setOther(policyConfigResponse.getConfig());
626 Properties props = new Properties();
627 props.putAll(policyConfigResponse.getProperty());
628 policyConfig.setProperties(props);
631 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
632 DocumentBuilder builder;
633 builder = factory.newDocumentBuilder();
634 policyConfig.setDocument(builder.parse(new InputSource(new StringReader(policyConfigResponse.getConfig()))));
637 } catch (Exception e) {
638 LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ e);
639 throw new PolicyConfigException(XACMLErrorConstants.ERROR_SCHEMA_INVALID+ "Unable to parse the config", e);
642 result.add(policyConfig);
648 private void setMatches(Map<String, String> matchingConditions) {
649 Matches match = new Matches();
650 HashMap<String, String> configAttributes = new HashMap<>();
652 for(String key: matchingConditions.keySet()){
653 if(key.equalsIgnoreCase("ONAPName")){
654 match.setOnapName(matchingConditions.get(key));
655 }else if(key.equalsIgnoreCase("ConfigName")){
656 match.setConfigName(matchingConditions.get(key));
658 configAttributes.put(key, matchingConditions.get(key));
661 if(!configAttributes.isEmpty()){
662 match.setConfigAttributes(configAttributes);
664 MatchStore.storeMatch(match);
666 LOGGER.info("StoreMatch failed for Onap:"
667 + match.getOnapName() + " Config: "
668 + match.getConfigName());
673 * Generic Rest Client to call PDP services.
675 private <T> ResponseEntity<T> callNewPDP(String resource,
676 HttpMethod method, Object body, Class<T> responseType) throws PolicyException{
677 RestTemplate restTemplate = new RestTemplate();
678 HttpEntity<?> requestEntity = new HttpEntity<>(body, getHeaders());
679 ResponseEntity<T> result = null;
680 HttpClientErrorException exception = null;
682 while(pdpsCount < pdps.size()){
684 result = restTemplate.exchange(pdps.get(0)+"/api/" + resource, method, requestEntity, responseType);
685 }catch(HttpClientErrorException e){
686 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
689 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps.get(0), e);
690 exception = new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
693 Collections.rotate(pdps, -1);
694 Collections.rotate(encoding, -1);
700 if(exception != null && exception.getStatusCode()!=null){
701 if(exception.getStatusCode().equals(HttpStatus.UNAUTHORIZED)){
702 String message = XACMLErrorConstants.ERROR_PERMISSIONS +":"+exception.getStatusCode()+":" +ERROR_AUTH_GET_PERM + resource;
703 LOGGER.error(message);
704 throw new PolicyException(message, exception);
706 if(exception.getStatusCode().equals(HttpStatus.BAD_REQUEST)){
707 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + ":"+exception.getStatusCode()+":" + exception.getResponseBodyAsString();
708 LOGGER.error(message);
709 throw new PolicyException(message, exception);
711 if(exception.getStatusCode().equals(HttpStatus.NOT_FOUND)){
712 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while connecting to " + pdps + exception;
713 LOGGER.error(message);
714 throw new PolicyException(message, exception);
716 String message = XACMLErrorConstants.ERROR_PROCESS_FLOW + ":"+exception.getStatusCode()+":" + exception.getResponseBodyAsString();
717 LOGGER.error(message);
718 throw new PolicyException(message, exception);
723 private HttpHeaders getHeaders() {
724 HttpHeaders headers = new HttpHeaders();
725 headers.set("ClientAuth", "Basic " + clientEncoding);
726 headers.set("Authorization", "Basic " + encoding.get(0));
727 if(contentType!=null){
728 headers.set("Content-Type", contentType.toString());
730 headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
732 headers.set("Environment", environment);
736 private void setClientEncoding() {
737 Base64.Encoder encoder = Base64.getEncoder();
738 clientEncoding = encoder.encodeToString((userName+":"+pass).getBytes(StandardCharsets.UTF_8));
741 public Collection<String> listConfigImpl(ConfigRequestParameters listRequestParameters) throws PolicyConfigException{
742 Collection<String> policyList = new ArrayList<>();
744 policyList.add("Policy Name: listConfigTest");
747 Collection<PolicyConfig> policyConfig = getConfigImpl(listRequestParameters);
748 for(PolicyConfig policy : policyConfig){
749 if(policy.getPolicyConfigMessage()!=null && policy.getPolicyConfigMessage().contains("PE300")){
750 policyList.add(policy.getPolicyConfigMessage());
752 policyList.add("Policy Name: " + policy.getPolicyName());
758 public Collection<PolicyResponse> sendEventImpl(Map<String, String> eventAttributes, UUID requestID) throws PolicyEventException {
759 String resource= "sendEvent";
760 ArrayList<PolicyResponse> response = new ArrayList<PolicyResponse>();
761 String body = new String();
764 // Long way here, can be shortened and will be done.
765 EventRequestParameters eventRequestParameters = new EventRequestParameters();
766 eventRequestParameters.setEventAttributes(eventAttributes);
767 eventRequestParameters.setRequestID(requestID);
768 body = PolicyUtils.objectToJsonString(eventRequestParameters);
769 } catch (JsonProcessingException e) {
770 String message = XACMLErrorConstants.ERROR_SCHEMA_INVALID + e;
771 LOGGER.error(message);
772 throw new PolicyEventException(message, e);
776 ResponseEntity<StdPolicyResponse[]> result = callNewPDP(resource, HttpMethod.POST, body, StdPolicyResponse[].class);
778 response = eventResult(result.getBody());
779 } catch (Exception exception) {
780 if(exception.getCause().getMessage().contains("401")){
781 String message = XACMLErrorConstants.ERROR_PERMISSIONS + ERROR_AUTH_GET_PERM + resource;
782 LOGGER.error(message);
783 throw new PolicyEventException(message, exception);
784 }if(exception.getCause().getMessage().contains("400")){
785 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Data is given.";
786 LOGGER.error(message);
787 throw new PolicyEventException(message, exception);
789 String message = XACMLErrorConstants.ERROR_PERMISSIONS+ "Unable to get valid Response from PDP(s) " + pdps;
790 LOGGER.error(message, exception);
791 throw new PolicyEventException(message, exception);
796 private ArrayList<PolicyResponse> eventResult(StdPolicyResponse[] response) throws PolicyEventException{
797 ArrayList<PolicyResponse> eventResult = new ArrayList<>();
798 if(response!=null && response.length>0){
799 for(StdPolicyResponse policyConfigResponse: response){
800 eventResult.add(policyConfigResponse);
806 private void setProperty(String propertyFilePath, String clientKey)
807 throws PolicyEngineException {
808 this.propertyFilePath = propertyFilePath;
809 if (this.propertyFilePath == null) {
810 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Error NO PropertyFile Path provided");
812 // Adding logic for remote Properties file.
813 Properties prop = new Properties();
814 if (propertyFilePath.startsWith("http")) {
817 configURL = new URL(propertyFilePath);
818 URLConnection connection = null;
819 connection = configURL.openConnection();
820 prop.load(connection.getInputStream());
821 } catch (IOException e) {
822 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
823 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Maformed property URL "+ e.getMessage());
826 Path file = Paths.get(propertyFilePath);
827 if (Files.notExists(file)) {
828 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "File doesn't exist in the specified Path " + file.toString());
830 if (file.toString().endsWith(".properties")) {
832 prop = new Properties();
834 in = new FileInputStream(file.toFile());
836 } catch (IOException e) {
837 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
838 throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Cannot Load the Properties file", e);
841 LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file " + propertyFilePath);
842 throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR + "Not a .properties file");
845 // UEB and DMAAP Settings
846 String check_type = prop.getProperty("NOTIFICATION_TYPE");
847 String serverList = prop.getProperty("NOTIFICATION_SERVERS");
848 topic = prop.getProperty("NOTIFICATION_TOPIC");
849 apiKey = prop.getProperty("UEB_API_KEY");
850 apiSecret = prop.getProperty("UEB_API_SECRET");
852 if(check_type==null) {
853 notificationType.add(DEFAULT_NOTIFICATION);
854 LOGGER.info("Properties file doesn't have the NOTIFICATION_TYPE parameter system will use defualt websockets");
856 check_type = check_type.trim();
857 if(check_type.contains(",")) {
858 typeDefault = new ArrayList<String>(Arrays.asList(prop.getProperty("NOTIFICATION_TYPE").split(",")));
859 notificationType = typeDefault;
861 notificationType = new ArrayList<>();
862 notificationType.add(check_type);
865 if(serverList==null) {
866 notificationType.clear();
867 notificationType.add(DEFAULT_NOTIFICATION);
868 LOGGER.info("Properties file doesn't have the NOTIFICATION_SERVERS parameter system will use defualt websockets");
870 serverList = serverList.trim();
871 if(serverList.contains(",")) {
872 notificationURLList = new ArrayList<String>(Arrays.asList(serverList.split(",")));
874 notificationURLList = new ArrayList<>();
875 notificationURLList.add(serverList);
880 topic = topic.trim();
882 LOGGER.error("Properties file doesn't have the NOTIFICATION_TOPIC parameter.");
885 // Client ID Authorization Settings.
886 String clientID = prop.getProperty("CLIENT_ID");
888 clientKey = prop.getProperty("CLIENT_KEY");
890 clientKey = PolicyUtils.decode(clientKey);
891 } catch (UnsupportedEncodingException|IllegalArgumentException e) {
892 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS+" Cannot Decode the given Password Proceeding with given Password!!");
895 if(clientID ==null || clientKey == null || clientID.isEmpty() || clientKey.isEmpty()){
896 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS+" Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
897 throw new PolicyEngineException(XACMLErrorConstants.ERROR_PERMISSIONS+ " Cannot proceed without the CLIENT_KEY and CLIENT_ID values !!");
899 userName = clientID.trim();
900 pass = clientKey.trim();
903 environment = prop.getProperty("ENVIRONMENT", AAFEnvironment.DEVL.toString());
904 if(environment.equalsIgnoreCase(AAFEnvironment.TEST.toString())){
905 environment = AAFEnvironment.TEST.toString();
906 }else if(environment.equalsIgnoreCase(AAFEnvironment.PROD.toString())){
907 environment = AAFEnvironment.PROD.toString();
909 environment = AAFEnvironment.DEVL.toString();
911 // Initializing the values.
912 pdps = new ArrayList<>();
913 encoding = new ArrayList<>();
914 // Check the Keys for PDP_URLs
915 Collection<Object> unsorted = prop.keySet();
916 @SuppressWarnings({ "rawtypes", "unchecked" })
917 List<String> sorted = new ArrayList(unsorted);
918 Collections.sort(sorted);
919 for (String propKey : sorted) {
920 if (propKey.startsWith("PDP_URL")) {
921 String check_val = prop.getProperty(propKey);
922 if (check_val == null) {
923 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Properties file doesn't have the PDP_URL parameter");
925 if (check_val.contains(";")) {
926 pdpDefault = new ArrayList<String>(Arrays.asList(check_val.split("\\s*;\\s*")));
928 while (pdpCount < pdpDefault.size()) {
929 String pdpVal = pdpDefault.get(pdpCount);
930 readPDPParam(pdpVal);
934 readPDPParam(check_val);
938 if (pdps == null || pdps.isEmpty()) {
939 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
940 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot Proceed without PDP_URLs");
943 // Get JUNIT property from properties file when running tests
944 String junit = prop.getProperty("JUNIT");
945 if(junit == null || junit.isEmpty()){
946 LOGGER.info("No JUNIT property provided, this will not be executed as a test.");
948 if(junit.equalsIgnoreCase("test")){
949 StdPolicyEngine.junit = true;
951 StdPolicyEngine.junit = false;
958 * Read the PDP_URL parameter
960 private void readPDPParam(String pdpVal) throws PolicyEngineException{
961 if(pdpVal.contains(",")){
962 List<String> pdpValues = new ArrayList<String>(Arrays.asList(pdpVal.split("\\s*,\\s*")));
963 if(pdpValues.size()==3){
965 pdps.add(pdpValues.get(0));
966 // 1:2 will be UserID:Password
967 String userID = pdpValues.get(1);
968 String pass = pdpValues.get(2);
969 Base64.Encoder encoder = Base64.getEncoder();
970 encoding.add(encoder.encodeToString((userID+":"+pass).getBytes(StandardCharsets.UTF_8)));
972 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Credentials to send Request: " + pdpValues);
973 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "No enough Credentials to send Request. " + pdpValues);
976 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values: " + pdpVal);
977 throw new PolicyEngineException(XACMLErrorConstants.ERROR_DATA_ISSUE + "PDP value is improper/missing required values.");
981 * Allowing changes to the scheme and Handler.
983 public void notification(NotificationScheme scheme, NotificationHandler handler) {
984 this.scheme = scheme;
985 this.handler = handler;
986 LOGGER.debug("Scheme is : " + scheme.toString());
987 LOGGER.debug("Handler is : " + handler.getClass().getName());
989 if (notificationType.get(0).equals("ueb")){
990 if (this.uebThread) {
991 uebClientThread.setAuto(scheme, handler);
992 this.uebThread = registerUEBThread.isAlive();
994 } else if (notificationType.get(0).equals("dmaap")){
995 if (this.dmaapThread) {
996 dmaapClientThread.setAuto(scheme, handler);
997 this.dmaapThread = registerDMAAPThread.isAlive();
1000 AutoClientEnd.setAuto(scheme, handler);
1008 if (notificationType.get(0).equals("ueb") && !this.uebThread){
1009 this.uebClientThread = new AutoClientUEB(pdps.get(0), notificationURLList, apiKey, apiSecret);
1010 this.uebClientThread.setAuto(scheme, handler);
1011 this.registerUEBThread = new Thread(this.uebClientThread);
1012 this.registerUEBThread.start();
1013 this.uebThread = true;
1014 }else if (notificationType.get(0).equals("dmaap") && !this.dmaapThread){
1015 this.dmaapClientThread = new AutoClientDMAAP(notificationURLList,topic,userName,pass);
1016 this.dmaapClientThread.setAuto(scheme, handler);
1017 this.registerDMAAPThread = new Thread(this.dmaapClientThread);
1018 this.registerDMAAPThread.start();
1019 this.dmaapThread = true;
1021 if(pdps.get(0)!=null){
1022 if(AutoClientEnd.getURL()==null){
1023 AutoClientEnd.start(pdps.get(0));
1025 AutoClientEnd.stop();
1026 AutoClientEnd.start(pdps.get(0));
1034 * Gets the Notification if one exists. Used only for Manual Polling
1037 public PDPNotification getNotification(){
1038 //Check if there is proper scheme..
1039 PDPNotification notification = null;
1040 if(this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS) || this.scheme.equals(NotificationScheme.MANUAL_NOTIFICATIONS)) {
1041 if (notificationType.get(0).equals("ueb")){
1042 ManualClientEndUEB.start(pdps.get(0), notificationURLList, UNIQUEID);
1043 notification = ManualClientEndUEB.result(scheme);
1044 }else if (notificationType.get(0).equals("dmaap")){
1045 ManualClientEndDMAAP.start(notificationURLList, topic, UNIQUEID, userName, pass);
1046 notification = ManualClientEndDMAAP.result(scheme);
1048 ManualClientEnd.start(pdps.get(0));
1049 LOGGER.debug("manual notification requested.. : " + scheme.toString());
1050 notification = ManualClientEnd.result(scheme);
1052 if (notification == null){
1053 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "No Notification yet..");
1056 return notification;
1064 * Setting the Scheme.
1066 public void setScheme(NotificationScheme scheme) {
1067 this.scheme = scheme;
1068 if (notificationType.get(0).equals("ueb")){
1069 AutoClientUEB.setScheme(this.scheme);
1070 if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)){
1071 ManualClientEndUEB.createTopic(pdps.get(0), UNIQUEID, notificationURLList);
1073 }else if (notificationType.get(0).equals("dmaap")){
1074 AutoClientDMAAP.setScheme(this.scheme);
1075 if (this.scheme.equals(NotificationScheme.MANUAL_ALL_NOTIFICATIONS)){
1076 ManualClientEndDMAAP.createTopic(topic, UNIQUEID, notificationURLList, userName, pass);
1079 AutoClientEnd.setScheme(this.scheme);
1084 * Returns the Scheme
1086 public NotificationScheme getScheme() {
1091 * Returns the NotificationHandler
1093 public NotificationHandler getNotificationHandler() {
1094 return this.handler;
1098 * Stop the Notification Service if its running.
1100 public void stopNotification() {
1101 if (this.scheme != null && this.handler != null) {
1102 if (this.scheme.equals(NotificationScheme.AUTO_ALL_NOTIFICATIONS)
1104 .equals(NotificationScheme.AUTO_NOTIFICATIONS)) {
1105 LOGGER.info("Clear Notification called.. ");
1106 if (notificationType.get(0).equals("ueb")){
1107 this.uebClientThread.terminate();
1108 this.uebThread = false;
1109 }else if (notificationType.get(0).equals("dmaap")){
1110 this.dmaapClientThread.terminate();
1111 this.dmaapThread = false;
1113 AutoClientEnd.stop();
1120 * Push a policy to the PDP API implementation
1122 public String pushPolicy(String policyScope, String policyName, String policyType, String pdpGroup, UUID requestID) throws PolicyException {
1123 PushPolicyParameters pushPolicyParameters = new PushPolicyParameters();
1124 if(policyScope==null|| policyScope.trim().isEmpty()){
1125 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1126 LOGGER.error(message);
1127 throw new PolicyException(message);
1129 if(policyName==null|| policyName.trim().isEmpty()){
1130 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1131 LOGGER.error(message);
1132 throw new PolicyException(message);
1134 pushPolicyParameters.setPolicyName(policyScope+"."+policyName);
1135 pushPolicyParameters.setPolicyType(policyType);
1136 pushPolicyParameters.setPdpGroup(pdpGroup);
1137 pushPolicyParameters.setRequestID(requestID);
1138 return pushPolicyImpl(pushPolicyParameters).getResponseMessage();
1141 public String createUpdateConfigPolicy(String policyName, String policyDescription, String onapName, String configName,
1142 Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
1143 String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
1144 return createUpdateConfigPolicyImpl(policyName, policyDescription, onapName, configName,
1145 configAttributes, configType, body, policyScope, requestID,
1146 riskLevel, riskType, guard, ttlDate, updateFlag);
1150 * Create Config Policy API Implementation
1152 public String createUpdateConfigPolicyImpl(String policyName, String policyDescription, String onapName, String configName,
1153 Map<String, String> configAttributes, String configType, String body, String policyScope, UUID requestID,
1154 String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
1155 PolicyParameters policyParameters = new PolicyParameters();
1156 policyParameters.setPolicyClass(PolicyClass.Config);
1157 policyParameters.setPolicyConfigType(PolicyConfigType.Base);
1158 if(policyScope==null|| policyScope.trim().isEmpty()){
1159 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1160 LOGGER.error(message);
1161 throw new PolicyException(message);
1163 if(policyName==null|| policyName.trim().isEmpty()){
1164 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1165 LOGGER.error(message);
1166 throw new PolicyException(message);
1168 policyParameters.setPolicyName(policyScope+"."+policyName);
1169 policyParameters.setPolicyDescription(policyDescription);
1170 policyParameters.setOnapName(onapName);
1171 policyParameters.setConfigName(configName);
1172 Map<AttributeType, Map<String, String>> attributes = new HashMap<AttributeType, Map<String, String>>();
1173 attributes.put(AttributeType.MATCHING, configAttributes);
1174 policyParameters.setAttributes(attributes);
1175 policyParameters.setConfigBodyType(PolicyType.valueOf(configType));
1176 policyParameters.setConfigBody(body);
1177 policyParameters.setRequestID(requestID);
1178 policyParameters.setRiskLevel(riskLevel);
1179 policyParameters.setRiskType(riskType);
1180 policyParameters.setGuard(Boolean.parseBoolean(guard));
1182 policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
1183 } catch (ParseException e) {
1184 LOGGER.warn("Error Parsing date given " + ttlDate);
1185 policyParameters.setTtlDate(null);
1187 return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
1190 public String createUpdateConfigFirewallPolicy(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
1191 String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
1192 return createUpdateConfigFirewallPolicyImpl(policyName, firewallJson, policyScope, requestID,
1193 riskLevel, riskType, guard, ttlDate, updateFlag);
1197 * Create Update Config Firewall Policy API implementation
1199 public String createUpdateConfigFirewallPolicyImpl(String policyName, JsonObject firewallJson, String policyScope, UUID requestID,
1200 String riskLevel, String riskType, String guard, String ttlDate, boolean updateFlag) throws PolicyException {
1201 PolicyParameters policyParameters = new PolicyParameters();
1202 policyParameters.setPolicyClass(PolicyClass.Config);
1203 policyParameters.setPolicyConfigType(PolicyConfigType.Firewall);
1204 if(policyScope==null|| policyScope.trim().isEmpty()){
1205 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Scope given.";
1206 LOGGER.error(message);
1207 throw new PolicyException(message);
1209 if(policyName==null|| policyName.trim().isEmpty()){
1210 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Policy Name given.";
1211 LOGGER.error(message);
1212 throw new PolicyException(message);
1214 policyParameters.setPolicyName(policyScope+"."+policyName);
1215 policyParameters.setConfigBody(firewallJson.toString());
1216 policyParameters.setRequestID(requestID);
1217 policyParameters.setRiskLevel(riskLevel);
1218 policyParameters.setRiskType(riskType);
1219 policyParameters.setGuard(Boolean.parseBoolean(guard));
1221 policyParameters.setTtlDate(new SimpleDateFormat("dd-MM-yyyy").parse(ttlDate));
1222 } catch (NullPointerException | ParseException e) {
1223 LOGGER.warn("Error Parsing date given " + ttlDate);
1224 policyParameters.setTtlDate(null);
1226 return createUpdatePolicyImpl(policyParameters, updateFlag).getResponseMessage();
1229 public void setClientKey(String clientKey){
1230 if(clientKey!=null && !clientKey.isEmpty()){
1231 StdPolicyEngine.pass = clientKey;
1232 setClientEncoding();
1236 * Get the Environment.
1238 public static String getEnvironment() {
1242 * Rotate the PDP list upon WEBsocket Failures
1244 public static void rotatePDPList() {
1245 Collections.rotate(pdps, -1);
1246 Collections.rotate(encoding, -1);
1249 * Get the latest PDP
1251 public static String getPDPURL() {