2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pdp.rest.api.services;
23 import com.att.research.xacml.api.Decision;
24 import com.att.research.xacml.api.Request;
25 import com.att.research.xacml.api.Response;
26 import com.att.research.xacml.std.dom.DOMRequest;
27 import com.att.research.xacml.std.dom.DOMResponse;
28 import com.att.research.xacml.std.json.JSONRequest;
29 import com.att.research.xacml.std.json.JSONResponse;
30 import java.util.Collection;
32 import java.util.Map.Entry;
33 import java.util.UUID;
34 import javax.json.Json;
35 import javax.json.JsonArrayBuilder;
36 import javax.json.JsonObject;
37 import javax.json.JsonObjectBuilder;
38 import org.apache.commons.text.StringEscapeUtils;
39 import org.apache.commons.lang3.StringUtils;
40 import org.onap.policy.api.DecisionRequestParameters;
41 import org.onap.policy.api.DecisionResponse;
42 import org.onap.policy.api.PolicyDecision;
43 import org.onap.policy.api.PolicyDecisionException;
44 import org.onap.policy.common.logging.flexlogger.FlexLogger;
45 import org.onap.policy.common.logging.flexlogger.Logger;
46 import org.onap.policy.pdp.rest.api.models.PDPResponse;
47 import org.onap.policy.std.StdDecisionResponse;
48 import org.onap.policy.xacml.api.XACMLErrorConstants;
49 import org.springframework.http.HttpStatus;
53 public class GetDecisionService {
54 private static final Logger LOGGER = FlexLogger.getLogger(GetDecisionService.class.getName());
56 private DecisionResponse decisionResponse = null;
57 private HttpStatus status = HttpStatus.BAD_REQUEST;
58 private DecisionRequestParameters decisionRequestParameters = null;
59 private String message = null;
60 private String onapComponentName = null;
61 private Map<String, String> decisionAttributes = null;
62 private UUID requestUuid = null;
63 private String requestType = null;
66 * Instantiates a new gets the decision service.
68 * @param decisionRequestParameters the decision request parameters
69 * @param requestId the request id
71 public GetDecisionService(DecisionRequestParameters decisionRequestParameters, String requestId) {
72 this.decisionRequestParameters = decisionRequestParameters;
73 if (decisionRequestParameters.getRequestID() == null) {
74 if (!StringUtils.isBlank(requestId)) {
76 requestUuid = UUID.fromString(requestId);
77 } catch (IllegalArgumentException e) {
78 requestUuid = UUID.randomUUID();
79 LOGGER.info("Generated Random UUID: " + requestUuid.toString(), e);
82 requestUuid = UUID.randomUUID();
83 LOGGER.info("Generated Random UUID: " + requestUuid.toString());
85 this.decisionRequestParameters.setRequestID(requestUuid);
89 } catch (PolicyDecisionException e) {
90 StdDecisionResponse decisionResp = new StdDecisionResponse();
91 decisionResp.setDecision(PolicyDecision.ERROR);
92 decisionResp.setDetails(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
93 this.decisionResponse = decisionResp;
94 status = HttpStatus.BAD_REQUEST;
98 private void run() throws PolicyDecisionException {
100 if (!getValidation()) {
101 LOGGER.error(message);
102 throw new PolicyDecisionException(message);
106 // first check whether it is a raw xacml req
107 if (!StringUtils.isBlank(requestType) && PDPServices.DECISION_RAW_XACML.equals(requestType)) {
108 this.setRequestType(PDPServices.DECISION_RAW_XACML);
109 processRawXacmlReq();
114 String modelString = getModel().toString();
115 LOGGER.debug("Generated JSON Request is: " + modelString);
118 PDPServices pdpServices = new PDPServices();
119 if (modelString.contains(PDPServices.RAINYDAY_TYPE)) {
120 pdpServices.setRequestType(PDPServices.RAINYDAY_TYPE);
121 this.setRequestType(PDPServices.RAINYDAY_TYPE);
122 } else if (PDPServices.DECISION_MS_NAMING_TYPE.equals(requestType)) {
123 pdpServices.setRequestType(PDPServices.DECISION_MS_NAMING_TYPE);
125 status = HttpStatus.OK;
126 decisionResponse = decisionResult(
127 pdpServices.generateRequest(modelString, decisionRequestParameters.getRequestID(), false, true));
128 } catch (Exception e) {
129 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
130 status = HttpStatus.BAD_REQUEST;
131 throw new PolicyDecisionException(e);
135 private void processRawXacmlReq() throws PolicyDecisionException {
136 Request pdpRequest = null;
137 Response pdpResponse = null;
140 PDPServices pdpServices = new PDPServices();
141 pdpServices.setRequestType(PDPServices.DECISION_RAW_XACML);
142 String rawXacmlReq = decisionAttributes.get(PDPServices.DECISION_RAW_XACML);
143 if (StringUtils.isBlank(rawXacmlReq)) {
144 LOGGER.error("Raw XACML request cannot be empty.");
145 throw new PolicyDecisionException(
146 "Raw XACML request cannot be empty. Please provide the XACML request in "
147 + PDPServices.DECISION_RAW_XACML);
149 String rawXacmlReqMode = decisionAttributes.get(PDPServices.DECISION_RAW_XACML_TYPE);
150 String reqType = PDPServices.DECISION_RAW_XACML_XML_TYPE;
151 if (!StringUtils.isBlank(rawXacmlReqMode)
152 && PDPServices.DECISION_RAW_XACML_JSON_TYPE.equalsIgnoreCase(rawXacmlReqMode.trim())) {
153 pdpRequest = JSONRequest.load(rawXacmlReq);
154 reqType = PDPServices.DECISION_RAW_XACML_JSON_TYPE;
156 pdpRequest = DOMRequest.load(StringEscapeUtils.unescapeXml(rawXacmlReq));
157 pdpServices.setRequestFormat(PDPServices.DECISION_RAW_XACML_XML_TYPE);
160 status = HttpStatus.OK;
161 pdpResponse = pdpServices.callPdp(pdpRequest, getRequestUuid());
163 String outgoingResponseString = null;
164 if (PDPServices.DECISION_RAW_XACML_JSON_TYPE.equalsIgnoreCase(reqType)) {
165 outgoingResponseString = JSONResponse.toString(pdpResponse, false);
167 outgoingResponseString = DOMResponse.toString(pdpResponse, false);
168 if (!StringUtils.isBlank(outgoingResponseString)) {
169 outgoingResponseString = StringEscapeUtils.escapeXml10(outgoingResponseString);
173 LOGGER.info("processRawXacmlReq - Request - \n" + rawXacmlReq + "\n Reponse:\n" + outgoingResponseString);
174 StdDecisionResponse decisionResp = new StdDecisionResponse();
175 if (!StringUtils.isBlank(outgoingResponseString)
176 && outgoingResponseString.contains(Decision.PERMIT.toString())) {
177 decisionResp.setDecision(PolicyDecision.PERMIT);
178 } else if (!StringUtils.isBlank(outgoingResponseString)
179 && outgoingResponseString.contains(Decision.DENY.toString())) {
180 decisionResp.setDecision(PolicyDecision.DENY);
182 decisionResp.setDecision(PolicyDecision.ERROR);
184 decisionResp.setDetails(outgoingResponseString);
185 this.decisionResponse = decisionResp;
186 } catch (Exception e) {
187 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e);
188 status = HttpStatus.BAD_REQUEST;
189 throw new PolicyDecisionException(e);
193 private DecisionResponse decisionResult(Collection<PDPResponse> generateRequest) {
194 StdDecisionResponse policyDecision = new StdDecisionResponse();
195 if (generateRequest == null) {
196 return policyDecision;
198 if (!generateRequest.isEmpty()) {
199 for (PDPResponse stdStatus : generateRequest) {
200 policyDecision.setDecision(stdStatus.getDecision());
201 policyDecision.setDetails(stdStatus.getDetails());
204 return policyDecision;
207 private JsonObject getModel() throws PolicyDecisionException {
208 JsonArrayBuilder resourceArray = Json.createArrayBuilder();
209 for (Entry<String, String> entry : decisionAttributes.entrySet()) {
210 if (entry.getKey().isEmpty()) {
211 String msg = XACMLErrorConstants.ERROR_DATA_ISSUE + "Cannot have an Empty Key";
213 throw new PolicyDecisionException(msg);
215 if (PDPServices.DECISION_MS_NAMING_TYPE.equalsIgnoreCase(entry.getKey().trim())) {
216 // this is used for only Model execution and not for identifying
217 // policy. It is input data for MS Naming model execution and
218 // will be parsed in the naming service. Skip here.
219 this.setRequestType(PDPServices.DECISION_MS_NAMING_TYPE);
223 JsonObjectBuilder resourceBuilder = Json.createObjectBuilder();
224 if (entry.getValue().matches("[0-9]+")) {
226 if ((entry.getKey().equals("ErrorCode")) || (entry.getKey().equals("WorkStep"))) {
228 resourceBuilder.add("Value", entry.getValue());
232 int val = Integer.parseInt(entry.getValue());
233 resourceBuilder.add("Value", val);
238 resourceBuilder.add("Value", entry.getValue());
240 resourceBuilder.add("AttributeId", entry.getKey());
241 resourceArray.add(resourceBuilder);
243 return Json.createObjectBuilder().add("Request", Json.createObjectBuilder().add("AccessSubject",
244 Json.createObjectBuilder().add("Attribute",
245 Json.createObjectBuilder().add("Value", onapComponentName).add("AttributeId", "ONAPName")))
246 .add("Resource", Json.createObjectBuilder().add("Attribute", resourceArray))
247 .add("Action", Json.createObjectBuilder().add("Attribute", Json.createObjectBuilder()
248 .add("Value", "DECIDE").add("AttributeId", "urn:oasis:names:tc:xacml:1.0:action:action-id"))))
252 private boolean getValidation() {
253 if (decisionRequestParameters == null) {
254 message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Request Paramaters";
257 onapComponentName = decisionRequestParameters.getOnapName();
258 decisionAttributes = decisionRequestParameters.getDecisionAttributes();
259 if (decisionAttributes == null || decisionAttributes.isEmpty()) {
260 message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No Decision Attributes Given. ";
263 if (decisionAttributes.containsKey(PDPServices.DECISION_RAW_XACML)) {
264 // onapName not mandatory for raw requests
265 requestType = PDPServices.DECISION_RAW_XACML;
266 } else if (onapComponentName == null || onapComponentName.isEmpty()) {
267 message = XACMLErrorConstants.ERROR_DATA_ISSUE + "No onapComponentName given : " + onapComponentName;
274 public DecisionResponse getResult() {
275 return decisionResponse;
278 public HttpStatus getResponseCode() {
282 public UUID getRequestUuid() {
286 public void setRequestUuid(UUID requestId) {
287 this.requestUuid = requestId;
290 public String getRequestType() {
294 public void setRequestType(String requestType) {
295 this.requestType = requestType;