2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021 Nordix Foundation.
7 * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.pap.main.rest;
25 import com.google.re2j.PatternSyntaxException;
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.Extension;
32 import io.swagger.annotations.ExtensionProperty;
33 import io.swagger.annotations.ResponseHeader;
34 import java.util.Collection;
35 import java.util.UUID;
36 import javax.ws.rs.GET;
37 import javax.ws.rs.HeaderParam;
38 import javax.ws.rs.Path;
39 import javax.ws.rs.PathParam;
40 import javax.ws.rs.QueryParam;
41 import javax.ws.rs.core.Response;
42 import org.onap.policy.models.base.PfModelException;
43 import org.onap.policy.models.base.PfModelRuntimeException;
44 import org.onap.policy.models.pap.concepts.PolicyStatus;
45 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifierOptVersion;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
51 * Class to provide REST end points for PAP component to retrieve the status of deployed
54 public class PolicyStatusControllerV1 extends PapRestControllerV1 {
55 private static final String EMPTY_REGEX_ERROR_MESSAGE = "An empty string passed as a regex is not allowed";
56 private static final String EMPTY_REGEX_WARNING = ". Empty string passed as Regex.";
57 private static final String GET_DEPLOYMENTS_FAILED = "get deployments failed";
59 private static final Logger logger = LoggerFactory.getLogger(PolicyStatusControllerV1.class);
61 private final PolicyStatusProvider provider = new PolicyStatusProvider();
64 * Queries status of all deployed policies. If regex is not null or empty, the function will only return
65 * policies that match regex
67 * @param requestId request ID used in ONAP logging
68 * @param regex regex for a policy name
73 @Path("policies/deployed")
74 @ApiOperation(value = "Queries status of all deployed policies",
75 notes = "Queries status of all deployed policies, returning success and failure counts of the PDPs",
76 responseContainer = "List", response = PolicyStatus.class,
77 tags = {"Policy Deployment Status"},
78 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
80 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
81 response = String.class),
82 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
83 response = String.class),
84 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
85 response = String.class),
86 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
87 response = UUID.class)},
89 @Extension(name = EXTENSION_NAME,
91 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
92 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
95 @ApiResponses(value = {
96 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
97 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
98 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
102 public Response queryAllDeployedPolicies(
103 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
104 @ApiParam(value = "Regex for a policy name") @QueryParam("regex") String regex) {
106 final Collection<PolicyStatus> result;
108 result = provider.getStatus();
109 } else if (regex.isBlank()) {
110 return makeRegexNotFoundResponse(requestId);
112 result = provider.getByRegex(regex);
114 return makeListOrNotFoundResponse(requestId, result);
116 } catch (PfModelException | PfModelRuntimeException e) {
117 logger.warn(GET_DEPLOYMENTS_FAILED, e);
118 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
119 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
120 } catch (PatternSyntaxException e) {
121 logger.warn(GET_DEPLOYMENTS_FAILED, e);
122 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)), requestId)
123 .entity(e.getMessage()).build();
129 * Queries status of specific deployed policies.
131 * @param requestId request ID used in ONAP logging
136 @Path("policies/deployed/{name}")
137 @ApiOperation(value = "Queries status of specific deployed policies",
138 notes = "Queries status of specific deployed policies, returning success and failure counts of the PDPs",
139 responseContainer = "List", response = PolicyStatus.class,
140 tags = {"Policy Deployment Status"},
141 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
143 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
144 response = String.class),
145 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
146 response = String.class),
147 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
148 response = String.class),
149 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
150 response = UUID.class)},
152 @Extension(name = EXTENSION_NAME,
154 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
155 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
158 @ApiResponses(value = {
159 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
160 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
161 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
165 public Response queryDeployedPolicies(
166 @ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
167 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
170 Collection<PolicyStatus> result = provider.getStatus(new ToscaConceptIdentifierOptVersion(name, null));
171 if (result.isEmpty()) {
172 return makeNotFoundResponse(requestId);
175 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
176 .entity(result).build();
179 } catch (PfModelException | PfModelRuntimeException e) {
180 logger.warn(GET_DEPLOYMENTS_FAILED, e);
181 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
182 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
188 * Queries status of a specific deployed policy.
190 * @param requestId request ID used in ONAP logging
195 @Path("policies/deployed/{name}/{version}")
196 @ApiOperation(value = "Queries status of a specific deployed policy",
197 notes = "Queries status of a specific deployed policy, returning success and failure counts of the PDPs",
198 response = PolicyStatus.class,
199 tags = {"Policy Deployment Status"},
200 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
202 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
203 response = String.class),
204 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
205 response = String.class),
206 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
207 response = String.class),
208 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
209 response = UUID.class)},
211 @Extension(name = EXTENSION_NAME,
213 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
214 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
217 @ApiResponses(value = {
218 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
219 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
220 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
224 public Response queryDeployedPolicy(@ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
225 @ApiParam(value = "Policy Version", required = true) @PathParam("version") String version,
226 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
229 Collection<PolicyStatus> result = provider.getStatus(new ToscaConceptIdentifierOptVersion(name, version));
230 if (result.isEmpty()) {
231 return makeNotFoundResponse(requestId);
234 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
235 .entity(result.iterator().next()).build();
238 } catch (PfModelException | PfModelRuntimeException e) {
239 logger.warn(GET_DEPLOYMENTS_FAILED, e);
240 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
241 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
247 * Queries status of all policies.
249 * @param requestId request ID used in ONAP logging
254 @Path("policies/status")
255 @ApiOperation(value = "Queries status of policies in all PdpGroups",
256 notes = "Queries status of policies in all PdpGroups, "
257 + "returning status of policies in all the PDPs belonging to all PdpGroups",
258 responseContainer = "List", response = PdpPolicyStatus.class,
259 tags = {"Policy Status"},
260 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
262 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
263 response = String.class),
264 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
265 response = String.class),
266 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
267 response = String.class),
268 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
269 response = UUID.class)},
271 @Extension(name = EXTENSION_NAME,
273 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
274 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
277 @ApiResponses(value = {
278 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
279 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
280 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
284 public Response getStatusOfAllPolicies(
285 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
288 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
289 .entity(provider.getPolicyStatus()).build();
291 } catch (PfModelException | PfModelRuntimeException e) {
292 logger.warn(GET_DEPLOYMENTS_FAILED, e);
293 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
294 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
299 * Queries status of policies in a specific PdpGroup. if regex is not null or empty, the function will only return
300 * policies that match regex
302 * @param pdpGroupName name of the PdpGroup
303 * @param requestId request ID used in ONAP logging
304 * @param regex regex for a policy name
309 @Path("policies/status/{pdpGroupName}")
310 @ApiOperation(value = "Queries status of policies in a specific PdpGroup",
311 notes = "Queries status of policies in a specific PdpGroup, "
312 + "returning status of policies in all the PDPs belonging to the PdpGroup",
313 responseContainer = "List", response = PdpPolicyStatus.class,
314 tags = {"Policy Status"},
315 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
317 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
318 response = String.class),
319 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
320 response = String.class),
321 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
322 response = String.class),
323 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
324 response = UUID.class)},
326 @Extension(name = EXTENSION_NAME,
328 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
329 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
332 @ApiResponses(value = {
333 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
334 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
335 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
339 public Response getStatusOfPoliciesByGroup(
340 @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
341 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
342 @ApiParam(value = "Regex for a policy name") @QueryParam("regex") String regex) {
345 final Collection<PdpPolicyStatus> result;
347 result = provider.getPolicyStatus(pdpGroupName);
348 } else if (regex.isBlank()) {
349 return makeRegexNotFoundResponse(requestId);
351 result = provider.getPolicyStatusByRegex(pdpGroupName, regex);
353 return makeListOrNotFoundResponse(requestId, result);
355 } catch (PfModelException | PfModelRuntimeException e) {
356 logger.warn(GET_DEPLOYMENTS_FAILED, e);
357 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
358 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
359 } catch (PatternSyntaxException e) {
360 logger.warn(GET_DEPLOYMENTS_FAILED, e);
361 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)), requestId)
362 .entity(e.getMessage()).build();
367 * Queries status of all versions of a specific policy in a specific PdpGroup.
369 * @param pdpGroupName name of the PdpGroup
370 * @param policyName name of the Policy
371 * @param requestId request ID used in ONAP logging
376 @Path("policies/status/{pdpGroupName}/{policyName}")
377 @ApiOperation(value = "Queries status of all versions of a specific policy in a specific PdpGroup",
378 notes = "Queries status of all versions of a specific policy in a specific PdpGroup,"
379 + " returning status of all versions of the policy in the PDPs belonging to the PdpGroup",
380 responseContainer = "List", response = PdpPolicyStatus.class,
381 tags = {"Policy Administration (PAP) API"},
382 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
384 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
385 response = String.class),
386 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
387 response = String.class),
388 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
389 response = String.class),
390 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
391 response = UUID.class)},
393 @Extension(name = EXTENSION_NAME,
395 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
396 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
399 @ApiResponses(value = {
400 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
401 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
402 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
406 public Response getStatusOfPolicies(
407 @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
408 @ApiParam(value = "Policy Id", required = true) @PathParam("policyName") String policyName,
409 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
412 Collection<PdpPolicyStatus> result =
413 provider.getPolicyStatus(pdpGroupName, new ToscaConceptIdentifierOptVersion(policyName, null));
414 if (result.isEmpty()) {
415 return makeNotFoundResponse(requestId);
418 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
419 .entity(result).build();
422 } catch (PfModelException | PfModelRuntimeException e) {
423 logger.warn(GET_DEPLOYMENTS_FAILED, e);
424 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
425 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
431 * Queries status of a specific version of a specific policy in a specific PdpGroup.
433 * @param pdpGroupName name of the PdpGroup
434 * @param policyName name of the Policy
435 * @param policyVersion version of the Policy
436 * @param requestId request ID used in ONAP logging
441 @Path("policies/status/{pdpGroupName}/{policyName}/{policyVersion}")
442 @ApiOperation(value = "Queries status of a specific version of a specific policy in a specific PdpGroup",
443 notes = "Queries status of a specific version of a specific policy in a specific PdpGroup,"
444 + " returning status of the policy in the PDPs belonging to the PdpGroup",
445 response = PdpPolicyStatus.class,
446 tags = {"Policy Administration (PAP) API"},
447 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
449 @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
450 response = String.class),
451 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
452 response = String.class),
453 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
454 response = String.class),
455 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
456 response = UUID.class)},
458 @Extension(name = EXTENSION_NAME,
460 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
461 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
464 @ApiResponses(value = {
465 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
466 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
467 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
471 public Response getStatusOfPolicy(
472 @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
473 @ApiParam(value = "Policy Id", required = true) @PathParam("policyName") String policyName,
474 @ApiParam(value = "Policy Version", required = true) @PathParam("policyVersion") String policyVersion,
475 @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
478 Collection<PdpPolicyStatus> result = provider.getPolicyStatus(pdpGroupName,
479 new ToscaConceptIdentifierOptVersion(policyName, policyVersion));
480 if (result.isEmpty()) {
481 return makeNotFoundResponse(requestId);
484 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
485 .entity(result.iterator().next()).build();
488 } catch (PfModelException | PfModelRuntimeException e) {
489 logger.warn(GET_DEPLOYMENTS_FAILED, e);
490 return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
491 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
496 * Makes a "not found" response.
498 * @param requestId request ID
499 * @return a "not found" response
501 private Response makeNotFoundResponse(final UUID requestId) {
502 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.NOT_FOUND)), requestId)
506 private Response makeRegexNotFoundResponse(UUID requestId) {
507 logger.warn(GET_DEPLOYMENTS_FAILED + EMPTY_REGEX_WARNING);
508 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)),
509 requestId).entity(EMPTY_REGEX_ERROR_MESSAGE).build();
512 private Response makeListOrNotFoundResponse(UUID requestId, Collection<?> result) {
513 if (result.isEmpty()) {
514 return makeNotFoundResponse(requestId);
516 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
517 .entity(result).build();