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