Merge "Query deployed policies by regex"
[policy/pap.git] / main / src / main / java / org / onap / policy / pap / main / rest / PolicyStatusControllerV1.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP PAP
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.policy.pap.main.rest;
24
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;
49
50 /**
51  * Class to provide REST end points for PAP component to retrieve the status of deployed
52  * policies.
53  */
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";
58
59     private static final Logger logger = LoggerFactory.getLogger(PolicyStatusControllerV1.class);
60
61     private final PolicyStatusProvider provider = new PolicyStatusProvider();
62
63     /**
64      * Queries status of all deployed policies. If regex is not null or empty, the function will only return
65      * policies that match regex
66      *
67      * @param requestId request ID used in ONAP logging
68      * @param regex regex for a policy name
69      * @return a response
70      */
71     // @formatter:off
72     @GET
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 Administration (PAP) API"},
78         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
79         responseHeaders = {
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)},
88         extensions = {@Extension(name = EXTENSION_NAME,
89             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
90                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
91     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
92                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
93                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
94     // @formatter:on
95
96     public Response queryAllDeployedPolicies(
97         @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
98         @ApiParam(value = "Regex for a policy name") @QueryParam("regex") String regex) {
99         try {
100             final Collection<PolicyStatus> result;
101             if (regex == null) {
102                 result = provider.getStatus();
103             } else if (regex.isBlank()) {
104                 return makeRegexNotFoundResponse(requestId);
105             } else {
106                 result = provider.getByRegex(regex);
107             }
108             return makeListOrNotFoundResponse(requestId, result);
109
110         } catch (PfModelException | PfModelRuntimeException e) {
111             logger.warn(GET_DEPLOYMENTS_FAILED, e);
112             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
113                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
114         } catch (PatternSyntaxException e) {
115             logger.warn(GET_DEPLOYMENTS_FAILED, e);
116             return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)), requestId)
117                 .entity(e.getMessage()).build();
118         }
119     }
120
121
122     /**
123      * Queries status of specific deployed policies.
124      *
125      * @param requestId request ID used in ONAP logging
126      * @return a response
127      */
128     // @formatter:off
129     @GET
130     @Path("policies/deployed/{name}")
131     @ApiOperation(value = "Queries status of specific deployed policies",
132         notes = "Queries status of specific deployed policies, returning success and failure counts of the PDPs",
133         responseContainer = "List", response = PolicyStatus.class,
134         tags = {"Policy Administration (PAP) API"},
135         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
136         responseHeaders = {
137             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
138                             response = String.class),
139             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
140                             response = String.class),
141             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
142                             response = String.class),
143             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
144                             response = UUID.class)},
145         extensions = {@Extension(name = EXTENSION_NAME,
146             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
147                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
148     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
149                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
150                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
151     // @formatter:on
152
153     public Response queryDeployedPolicies(
154                     @ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
155                     @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
156
157         try {
158             Collection<PolicyStatus> result = provider.getStatus(new ToscaConceptIdentifierOptVersion(name, null));
159             if (result.isEmpty()) {
160                 return makeNotFoundResponse(requestId);
161
162             } else {
163                 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
164                                 .entity(result).build();
165             }
166
167         } catch (PfModelException | PfModelRuntimeException e) {
168             logger.warn(GET_DEPLOYMENTS_FAILED, e);
169             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
170                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
171         }
172     }
173
174
175     /**
176      * Queries status of a specific deployed policy.
177      *
178      * @param requestId request ID used in ONAP logging
179      * @return a response
180      */
181     // @formatter:off
182     @GET
183     @Path("policies/deployed/{name}/{version}")
184     @ApiOperation(value = "Queries status of a specific deployed policy",
185         notes = "Queries status of a specific deployed policy, returning success and failure counts of the PDPs",
186         response = PolicyStatus.class,
187         tags = {"Policy Administration (PAP) API"},
188         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
189         responseHeaders = {
190             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
191                             response = String.class),
192             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
193                             response = String.class),
194             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
195                             response = String.class),
196             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
197                             response = UUID.class)},
198         extensions = {@Extension(name = EXTENSION_NAME,
199             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
200                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
201     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
202                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
203                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
204     // @formatter:on
205
206     public Response queryDeployedPolicy(@ApiParam(value = "Policy Id", required = true) @PathParam("name") String name,
207                     @ApiParam(value = "Policy Version", required = true) @PathParam("version") String version,
208                     @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
209
210         try {
211             Collection<PolicyStatus> result = provider.getStatus(new ToscaConceptIdentifierOptVersion(name, version));
212             if (result.isEmpty()) {
213                 return makeNotFoundResponse(requestId);
214
215             } else {
216                 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
217                                 .entity(result.iterator().next()).build();
218             }
219
220         } catch (PfModelException | PfModelRuntimeException e) {
221             logger.warn(GET_DEPLOYMENTS_FAILED, e);
222             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
223                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
224         }
225     }
226
227
228     /**
229      * Queries status of all policies.
230      *
231      * @param requestId request ID used in ONAP logging
232      * @return a response
233      */
234     // @formatter:off
235     @GET
236     @Path("policies/status")
237     @ApiOperation(value = "Queries status of policies in all PdpGroups",
238         notes = "Queries status of policies in all PdpGroups, "
239             + "returning status of policies in all the PDPs belonging to all PdpGroups",
240         responseContainer = "List", response = PdpPolicyStatus.class,
241         tags = {"Policy Administration (PAP) API"},
242         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
243         responseHeaders = {
244             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
245                             response = String.class),
246             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
247                             response = String.class),
248             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
249                             response = String.class),
250             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
251                             response = UUID.class)},
252         extensions = {@Extension(name = EXTENSION_NAME,
253             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
254                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
255     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
256                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
257                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
258     // @formatter:on
259
260     public Response getStatusOfAllPolicies(
261                     @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
262
263         try {
264             return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
265                             .entity(provider.getPolicyStatus()).build();
266
267         } catch (PfModelException | PfModelRuntimeException e) {
268             logger.warn(GET_DEPLOYMENTS_FAILED, e);
269             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
270                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
271         }
272     }
273
274     /**
275      * Queries status of policies in a specific PdpGroup. if regex is not null or empty, the function will only return
276      * policies that match regex
277      *
278      * @param pdpGroupName name of the PdpGroup
279      * @param requestId request ID used in ONAP logging
280      * @param regex regex for a policy name
281      * @return a response
282      */
283     // @formatter:off
284     @GET
285     @Path("policies/status/{pdpGroupName}")
286     @ApiOperation(value = "Queries status of policies in a specific PdpGroup",
287         notes = "Queries status of policies in a specific PdpGroup, "
288             + "returning status of policies in all the PDPs belonging to the PdpGroup",
289         responseContainer = "List", response = PdpPolicyStatus.class,
290         tags = {"Policy Administration (PAP) API"},
291         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
292         responseHeaders = {
293             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
294                             response = String.class),
295             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
296                             response = String.class),
297             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
298                             response = String.class),
299             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
300                             response = UUID.class)},
301         extensions = {@Extension(name = EXTENSION_NAME,
302             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
303                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
304     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
305                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
306                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
307     // @formatter:on
308
309     public Response getStatusOfPoliciesByGroup(
310         @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
311         @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId,
312         @ApiParam(value = "Regex for a policy name") @QueryParam("regex") String regex) {
313
314         try {
315             final Collection<PdpPolicyStatus> result;
316             if (regex == null) {
317                 result = provider.getPolicyStatus(pdpGroupName);
318             } else if (regex.isBlank()) {
319                 return makeRegexNotFoundResponse(requestId);
320             } else {
321                 result = provider.getPolicyStatusByRegex(pdpGroupName, regex);
322             }
323             return makeListOrNotFoundResponse(requestId, result);
324
325         } catch (PfModelException | PfModelRuntimeException e) {
326             logger.warn(GET_DEPLOYMENTS_FAILED, e);
327             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
328                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
329         } catch (PatternSyntaxException e) {
330             logger.warn(GET_DEPLOYMENTS_FAILED, e);
331             return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)), requestId)
332                 .entity(e.getMessage()).build();
333         }
334     }
335
336     /**
337      * Queries status of all versions of a specific policy in a specific PdpGroup.
338      *
339      * @param pdpGroupName name of the PdpGroup
340      * @param policyName name of the Policy
341      * @param requestId request ID used in ONAP logging
342      * @return a response
343      */
344     // @formatter:off
345     @GET
346     @Path("policies/status/{pdpGroupName}/{policyName}")
347     @ApiOperation(value = "Queries status of all versions of a specific policy in a specific PdpGroup",
348         notes = "Queries status of all versions of a specific policy in a specific PdpGroup,"
349             + " returning status of all versions of the policy in the PDPs belonging to the PdpGroup",
350         responseContainer = "List", response = PdpPolicyStatus.class,
351         tags = {"Policy Administration (PAP) API"},
352         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
353         responseHeaders = {
354             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
355                             response = String.class),
356             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
357                             response = String.class),
358             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
359                             response = String.class),
360             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
361                             response = UUID.class)},
362         extensions = {@Extension(name = EXTENSION_NAME,
363             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
364                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
365     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
366                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
367                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
368     // @formatter:on
369
370     public Response getStatusOfPolicies(
371         @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
372         @ApiParam(value = "Policy Id", required = true) @PathParam("policyName") String policyName,
373         @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
374
375         try {
376             Collection<PdpPolicyStatus> result =
377                 provider.getPolicyStatus(pdpGroupName, new ToscaConceptIdentifierOptVersion(policyName, null));
378             if (result.isEmpty()) {
379                 return makeNotFoundResponse(requestId);
380
381             } else {
382                 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
383                                 .entity(result).build();
384             }
385
386         } catch (PfModelException | PfModelRuntimeException e) {
387             logger.warn(GET_DEPLOYMENTS_FAILED, e);
388             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
389                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
390         }
391     }
392
393
394     /**
395      * Queries status of a specific version of a specific policy in a specific PdpGroup.
396      *
397      * @param pdpGroupName name of the PdpGroup
398      * @param policyName name of the Policy
399      * @param policyVersion version of the Policy
400      * @param requestId request ID used in ONAP logging
401      * @return a response
402      */
403     // @formatter:off
404     @GET
405     @Path("policies/status/{pdpGroupName}/{policyName}/{policyVersion}")
406     @ApiOperation(value = "Queries status of a specific version of a specific policy in a specific PdpGroup",
407         notes = "Queries status of a specific version of a specific policy in a specific PdpGroup,"
408             + " returning status of the policy in the PDPs belonging to the PdpGroup",
409         response = PdpPolicyStatus.class,
410         tags = {"Policy Administration (PAP) API"},
411         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
412         responseHeaders = {
413             @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
414                             response = String.class),
415             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
416                             response = String.class),
417             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
418                             response = String.class),
419             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
420                             response = UUID.class)},
421         extensions = {@Extension(name = EXTENSION_NAME,
422             properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
423                 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})})
424     @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
425                     @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
426                     @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
427     // @formatter:on
428
429     public Response getStatusOfPolicy(
430         @ApiParam(value = "PDP Group Name", required = true) @PathParam("pdpGroupName") String pdpGroupName,
431         @ApiParam(value = "Policy Id", required = true) @PathParam("policyName") String policyName,
432         @ApiParam(value = "Policy Version", required = true) @PathParam("policyVersion") String policyVersion,
433         @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) {
434
435         try {
436             Collection<PdpPolicyStatus> result = provider.getPolicyStatus(pdpGroupName,
437                 new ToscaConceptIdentifierOptVersion(policyName, policyVersion));
438             if (result.isEmpty()) {
439                 return makeNotFoundResponse(requestId);
440
441             } else {
442                 return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
443                                 .entity(result.iterator().next()).build();
444             }
445
446         } catch (PfModelException | PfModelRuntimeException e) {
447             logger.warn(GET_DEPLOYMENTS_FAILED, e);
448             return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())),
449                 requestId).entity(e.getErrorResponse().getErrorMessage()).build();
450         }
451     }
452
453     /**
454      * Makes a "not found" response.
455      *
456      * @param requestId request ID
457      * @return a "not found" response
458      */
459     private Response makeNotFoundResponse(final UUID requestId) {
460         return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.NOT_FOUND)), requestId)
461                         .build();
462     }
463
464     private Response makeRegexNotFoundResponse(UUID requestId) {
465         logger.warn(GET_DEPLOYMENTS_FAILED + EMPTY_REGEX_WARNING);
466         return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.BAD_REQUEST)),
467             requestId).entity(EMPTY_REGEX_ERROR_MESSAGE).build();
468     }
469
470     private Response makeListOrNotFoundResponse(UUID requestId, Collection<?> result) {
471         if (result.isEmpty()) {
472             return makeNotFoundResponse(requestId);
473         } else {
474             return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId)
475                 .entity(result).build();
476         }
477     }
478 }