Tie XACML REST Decision
[policy/xacml-pdp.git] / main / src / main / java / org / onap / policy / pdpx / main / rest / XacmlPdpRestController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019 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 io.swagger.annotations.Api;
24 import io.swagger.annotations.ApiOperation;
25 import io.swagger.annotations.ApiParam;
26 import io.swagger.annotations.ApiResponse;
27 import io.swagger.annotations.ApiResponses;
28 import io.swagger.annotations.Authorization;
29 import io.swagger.annotations.BasicAuthDefinition;
30 import io.swagger.annotations.Extension;
31 import io.swagger.annotations.ExtensionProperty;
32 import io.swagger.annotations.Info;
33 import io.swagger.annotations.ResponseHeader;
34 import io.swagger.annotations.SecurityDefinition;
35 import io.swagger.annotations.SwaggerDefinition;
36
37 import java.util.UUID;
38
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.MediaType;
46 import javax.ws.rs.core.Response;
47 import javax.ws.rs.core.Response.ResponseBuilder;
48
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
59 /**
60  * Class to provide xacml pdp REST services.
61  *
62  */
63 @Path("/policy/pdpx/v1")
64 @Api
65 @Produces(MediaType.APPLICATION_JSON)
66 @Consumes(MediaType.APPLICATION_JSON)
67 @SwaggerDefinition(info = @Info(description = "Policy Xacml PDP Service", version = "1.0.0", title = "Policy Xacml PDP",
68         extensions = {@Extension(properties = {@ExtensionProperty(name = "planned-retirement-date", value = "tbd"),
69                 @ExtensionProperty(name = "component", value = "Policy Framework")})}),
70         schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
71         securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
72 public class XacmlPdpRestController {
73
74     @GET
75     @Path("/healthcheck")
76     @ApiOperation(value = "Perform a system healthcheck",
77             notes = "Provides healthy status of the Policy Xacml PDP component", response = HealthCheckReport.class,
78             responseHeaders = {
79                     @ResponseHeader(name = "X-MinorVersion",
80                             description = "Used to request or communicate a MINOR version back from the client"
81                                     + " to the server, and from the server back to the client",
82                             response = String.class),
83                     @ResponseHeader(name = "X-PatchVersion",
84                             description = "Used only to communicate a PATCH version in a response for"
85                                     + " troubleshooting purposes only, and will not be provided by"
86                                     + " the client on request",
87                             response = String.class),
88                     @ResponseHeader(name = "X-LatestVersion",
89                             description = "Used only to communicate an API's latest version", response = String.class),
90                     @ResponseHeader(name = "X-ONAP-RequestID",
91                             description = "Used to track REST transactions for logging purpose",
92                             response = UUID.class)},
93             authorizations = @Authorization(value = "basicAuth"), tags = {"HealthCheck",},
94             extensions = {@Extension(name = "interface info",
95                     properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
96                             @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
97     @ApiResponses(value = {@ApiResponse(code = 401, message = "Authentication Error"),
98             @ApiResponse(code = 403, message = "Authorization Error"),
99             @ApiResponse(code = 500, message = "Internal Server Error")})
100     public Response healthcheck(
101             @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
102         return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
103                 .entity(new HealthCheckProvider().performHealthCheck()).build();
104     }
105
106     @GET
107     @Path("/statistics")
108     @ApiOperation(value = "Fetch current statistics",
109             notes = "Provides current statistics of the Policy Xacml PDP component", response = StatisticsReport.class,
110             responseHeaders = {
111                     @ResponseHeader(name = "X-MinorVersion",
112                             description = "Used to request or communicate a MINOR version back from the client"
113                                     + " to the server, and from the server back to the client",
114                             response = String.class),
115                     @ResponseHeader(name = "X-PatchVersion",
116                             description = "Used only to communicate a PATCH version in a response for"
117                                     + " troubleshooting purposes only, and will not be provided by"
118                                     + " the client on request",
119                             response = String.class),
120                     @ResponseHeader(name = "X-LatestVersion",
121                             description = "Used only to communicate an API's latest version", response = String.class),
122                     @ResponseHeader(name = "X-ONAP-RequestID",
123                             description = "Used to track REST transactions for logging purpose",
124                             response = UUID.class)},
125             authorizations = @Authorization(value = "basicAuth"), tags = {"Statistics",},
126             extensions = {@Extension(name = "interface info",
127                     properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
128                             @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
129     @ApiResponses(value = {@ApiResponse(code = 401, message = "Authentication Error"),
130             @ApiResponse(code = 403, message = "Authorization Error"),
131             @ApiResponse(code = 500, message = "Internal Server Error")})
132     public Response statistics(
133             @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
134         return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
135                 .entity(new StatisticsProvider().fetchCurrentStatistics()).build();
136     }
137
138     /**
139      * Our decision entry point.
140      *
141      * @param body Should be a DecisionRequest object
142      * @param requestId Unique request id
143      * @return DecisionResponse or ErrorResponse object
144      */
145     @POST
146     @Path("/decision")
147     @ApiOperation(value = "Fetch the decision using specified decision parameters",
148             notes = "Returns the policy decision from Policy Xacml PDP", response = DecisionResponse.class,
149             responseHeaders = {
150                     @ResponseHeader(name = "X-MinorVersion",
151                             description = "Used to request or communicate a MINOR version back from the client"
152                                     + " to the server, and from the server back to the client",
153                             response = String.class),
154                     @ResponseHeader(name = "X-PatchVersion",
155                             description = "Used only to communicate a PATCH version in a response for"
156                                     + " troubleshooting purposes only, and will not be provided by"
157                                     + " the client on request",
158                             response = String.class),
159                     @ResponseHeader(name = "X-LatestVersion",
160                             description = "Used only to communicate an API's latest version", response = String.class),
161                     @ResponseHeader(name = "X-ONAP-RequestID",
162                             description = "Used to track REST transactions for logging purpose",
163                             response = UUID.class)},
164             authorizations = @Authorization(value = "basicAuth"), tags = {"Decision",},
165             extensions = {@Extension(name = "interface info",
166                     properties = {@ExtensionProperty(name = "pdpx-version", value = "1.0.0"),
167                             @ExtensionProperty(name = "last-mod-release", value = "Dublin")})})
168     @ApiResponses(value = {@ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
169             @ApiResponse(code = 401, message = "Authentication Error"),
170             @ApiResponse(code = 403, message = "Authorization Error"),
171             @ApiResponse(code = 500, message = "Internal Server Error")})
172     public Response decision(DecisionRequest body,
173             @HeaderParam("X-ONAP-RequestID") @ApiParam("RequestID for http transaction") UUID requestId) {
174         try {
175             return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
176                     .entity(new DecisionProvider().fetchDecision(body)).build();
177         } catch (DecisionException e) {
178             return addLoggingHeaders(
179                     addVersionControlHeaders(Response.status((e.getErrorResponse().getResponseCode()))), requestId)
180                     .entity(e.getErrorResponse()).build();
181         }
182     }
183
184     private ResponseBuilder addVersionControlHeaders(ResponseBuilder rb) {
185         return rb.header("X-MinorVersion", "0").header("X-PatchVersion", "0").header("X-LatestVersion", "1.0.0");
186     }
187
188     private ResponseBuilder addLoggingHeaders(ResponseBuilder rb, UUID requestId) {
189         if (requestId == null) {
190             // Generate a random uuid if client does not embed requestId in rest request
191             return rb.header("X-ONAP-RequestID", UUID.randomUUID());
192         }
193         return rb.header("X-ONAP-RequestID", requestId);
194     }
195 }