2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
4 * Modifications Copyright (C) 2021 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.pdpx.main.rest;
24 import com.att.research.xacml.api.Request;
25 import io.swagger.annotations.Api;
26 import io.swagger.annotations.ApiOperation;
27 import io.swagger.annotations.ApiParam;
28 import io.swagger.annotations.ApiResponse;
29 import io.swagger.annotations.ApiResponses;
30 import io.swagger.annotations.Authorization;
31 import io.swagger.annotations.BasicAuthDefinition;
32 import io.swagger.annotations.Extension;
33 import io.swagger.annotations.ExtensionProperty;
34 import io.swagger.annotations.Info;
35 import io.swagger.annotations.ResponseHeader;
36 import io.swagger.annotations.SecurityDefinition;
37 import io.swagger.annotations.SwaggerDefinition;
38 import java.util.UUID;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.ws.rs.Consumes;
41 import javax.ws.rs.GET;
42 import javax.ws.rs.HeaderParam;
43 import javax.ws.rs.POST;
44 import javax.ws.rs.Path;
45 import javax.ws.rs.Produces;
46 import javax.ws.rs.core.Context;
47 import javax.ws.rs.core.MediaType;
48 import javax.ws.rs.core.Response;
49 import javax.ws.rs.core.Response.ResponseBuilder;
50 import org.onap.policy.common.endpoints.report.HealthCheckReport;
51 import org.onap.policy.models.decisions.concepts.DecisionException;
52 import org.onap.policy.models.decisions.concepts.DecisionRequest;
53 import org.onap.policy.models.decisions.concepts.DecisionResponse;
54 import org.onap.policy.models.errors.concepts.ErrorResponse;
55 import org.onap.policy.pdpx.main.rest.model.StatisticsReport;
56 import org.onap.policy.pdpx.main.rest.provider.DecisionProvider;
57 import org.onap.policy.pdpx.main.rest.provider.HealthCheckProvider;
58 import org.onap.policy.pdpx.main.rest.provider.StatisticsProvider;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
63 * Class to provide xacml pdp REST services.
66 @Path("/policy/pdpx/v1")
68 @Produces({MediaType.APPLICATION_JSON, XacmlPdpRestController.APPLICATION_YAML})
69 @Consumes({MediaType.APPLICATION_JSON, XacmlPdpRestController.APPLICATION_YAML})
70 @SwaggerDefinition(info = @Info(description = "Policy Xacml PDP Service", version = "1.0.0", title = "Policy Xacml PDP",
74 @ExtensionProperty(name = "planned-retirement-date", value = "tbd"),
75 @ExtensionProperty(name = "component", value = "Policy Framework")
78 schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
79 securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
80 public class XacmlPdpRestController {
81 private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpRestController.class);
82 public static final String APPLICATION_YAML = "application/yaml";
83 public static final String APPLICATION_XACML_JSON = "application/xacml+json";
84 public static final String APPLICATION_XACML_XML = "application/xacml+xml";
88 @ApiOperation(value = "Perform a system healthcheck",
89 notes = "Provides healthy status of the Policy Xacml PDP component", response = HealthCheckReport.class,
91 @ResponseHeader(name = "X-MinorVersion",
92 description = "Used to request or communicate a MINOR version back from the client"
93 + " to the server, and from the server back to the client",
94 response = String.class),
95 @ResponseHeader(name = "X-PatchVersion",
96 description = "Used only to communicate a PATCH version in a response for"
97 + " troubleshooting purposes only, and will not be provided by"
98 + " the client on request",
99 response = String.class),
100 @ResponseHeader(name = "X-LatestVersion",
101 description = "Used only to communicate an API's latest version", response = String.class),
102 @ResponseHeader(name = "X-ONAP-RequestID",
103 description = "Used to track REST transactions for logging purpose",
104 response = UUID.class)},
105 authorizations = @Authorization(value = "basicAuth"), tags = {"HealthCheck", },
107 @Extension(name = "interface info",
109 @ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
110 @ExtensionProperty(name = "last-mod-release", value = "Dublin")
113 @ApiResponses(value = {
114 @ApiResponse(code = 401, message = "Authentication Error"),
115 @ApiResponse(code = 403, message = "Authorization Error"),
116 @ApiResponse(code = 500, message = "Internal Server Error")})
117 public Response healthcheck(
118 @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
119 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
120 .entity(new HealthCheckProvider().performHealthCheck()).build();
125 @ApiOperation(value = "Fetch current statistics",
126 notes = "Provides current statistics of the Policy Xacml PDP component", response = StatisticsReport.class,
128 @ResponseHeader(name = "X-MinorVersion",
129 description = "Used to request or communicate a MINOR version back from the client"
130 + " to the server, and from the server back to the client",
131 response = String.class),
132 @ResponseHeader(name = "X-PatchVersion",
133 description = "Used only to communicate a PATCH version in a response for"
134 + " troubleshooting purposes only, and will not be provided by"
135 + " the client on request",
136 response = String.class),
137 @ResponseHeader(name = "X-LatestVersion",
138 description = "Used only to communicate an API's latest version", response = String.class),
139 @ResponseHeader(name = "X-ONAP-RequestID",
140 description = "Used to track REST transactions for logging purpose",
141 response = UUID.class)},
142 authorizations = @Authorization(value = "basicAuth"), tags = {"Statistics", },
144 @Extension(name = "interface info",
146 @ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
147 @ExtensionProperty(name = "last-mod-release", value = "Dublin")
150 @ApiResponses(value = {
151 @ApiResponse(code = 401, message = "Authentication Error"),
152 @ApiResponse(code = 403, message = "Authorization Error"),
153 @ApiResponse(code = 500, message = "Internal Server Error")})
154 public Response statistics(
155 @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
156 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
157 .entity(new StatisticsProvider().fetchCurrentStatistics()).build();
161 * Our decision entry point.
163 * @param body Should be a DecisionRequest object
164 * @param requestId Unique request id
165 * @return DecisionResponse or ErrorResponse object
169 @ApiOperation(value = "Fetch the decision using specified decision parameters",
170 notes = "Returns the policy decision from Policy Xacml PDP", response = DecisionResponse.class,
172 @ResponseHeader(name = "X-MinorVersion",
173 description = "Used to request or communicate a MINOR version back from the client"
174 + " to the server, and from the server back to the client",
175 response = String.class),
176 @ResponseHeader(name = "X-PatchVersion",
177 description = "Used only to communicate a PATCH version in a response for"
178 + " troubleshooting purposes only, and will not be provided by"
179 + " the client on request",
180 response = String.class),
181 @ResponseHeader(name = "X-LatestVersion",
182 description = "Used only to communicate an API's latest version", response = String.class),
183 @ResponseHeader(name = "X-ONAP-RequestID",
184 description = "Used to track REST transactions for logging purpose",
185 response = UUID.class)},
186 authorizations = @Authorization(value = "basicAuth"), tags = {"Decision", },
188 @Extension(name = "interface info",
190 @ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
191 @ExtensionProperty(name = "last-mod-release", value = "Dublin")
194 @ApiResponses(value = {
195 @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
196 @ApiResponse(code = 401, message = "Authentication Error"),
197 @ApiResponse(code = 403, message = "Authorization Error"),
198 @ApiResponse(code = 500, message = "Internal Server Error")})
199 public Response decision(DecisionRequest body,
200 @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId,
201 @Context HttpServletRequest request) {
203 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
204 .entity(new DecisionProvider().fetchDecision(body, request.getParameterMap())).build();
205 } catch (DecisionException e) {
206 LOGGER.error("Decision exception", e);
207 XacmlPdpStatisticsManager.getCurrent().updateErrorCount();
208 return addLoggingHeaders(
209 addVersionControlHeaders(Response.status((e.getErrorResponse().getResponseCode()))), requestId)
210 .entity(e.getErrorResponse()).build();
215 * Our native decision entry point.
217 * @param body Should be an Xacml Request object
218 * @param requestId Unique request id
219 * @return Xacml Response or ErrorResponse object
223 @Produces({XacmlPdpRestController.APPLICATION_XACML_JSON, XacmlPdpRestController.APPLICATION_XACML_XML})
224 @Consumes({XacmlPdpRestController.APPLICATION_XACML_JSON, XacmlPdpRestController.APPLICATION_XACML_XML})
225 @ApiOperation(value = "Fetch the decision using specified decision parameters",
226 notes = "Returns the policy decision from Policy Xacml PDP",
227 response = com.att.research.xacml.api.Response.class,
229 @ResponseHeader(name = "X-MinorVersion",
230 description = "Used to request or communicate a MINOR version back from the client"
231 + " to the server, and from the server back to the client",
232 response = String.class),
233 @ResponseHeader(name = "X-PatchVersion",
234 description = "Used only to communicate a PATCH version in a response for"
235 + " troubleshooting purposes only, and will not be provided by"
236 + " the client on request",
237 response = String.class),
238 @ResponseHeader(name = "X-LatestVersion",
239 description = "Used only to communicate an API's latest version", response = String.class),
240 @ResponseHeader(name = "X-ONAP-RequestID",
241 description = "Used to track REST transactions for logging purpose",
242 response = UUID.class)},
243 authorizations = @Authorization(value = "basicAuth"), tags = {"Decision", },
245 @Extension(name = "interface info",
247 @ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
248 @ExtensionProperty(name = "last-mod-release", value = "Frankfurt")
251 @ApiResponses(value = {
252 @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
253 @ApiResponse(code = 401, message = "Authentication Error"),
254 @ApiResponse(code = 403, message = "Authorization Error"),
255 @ApiResponse(code = 500, message = "Internal Server Error")})
256 public Response xacml(Request body,
257 @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
259 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
260 .entity(new DecisionProvider().fetchNativeDecision(body)).build();
261 } catch (DecisionException e) {
262 LOGGER.error("Decision exception", e);
263 XacmlPdpStatisticsManager.getCurrent().updateErrorCount();
264 return addLoggingHeaders(
265 addVersionControlHeaders(Response.status((e.getErrorResponse().getResponseCode()))), requestId)
266 .entity(e.getErrorResponse()).build();
270 private ResponseBuilder addVersionControlHeaders(ResponseBuilder rb) {
271 return rb.header("X-MinorVersion", "0").header("X-PatchVersion", "0").header("X-LatestVersion", "1.0.0");
274 private ResponseBuilder addLoggingHeaders(ResponseBuilder rb, UUID requestId) {
275 if (requestId == null) {
276 // Generate a random uuid if client does not embed requestId in rest request
277 return rb.header("X-ONAP-RequestID", UUID.randomUUID());
279 return rb.header("X-ONAP-RequestID", requestId);