Separate entity retrieval from jax-rs Response creation
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / rest / ExceptionHandler.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2023 Deutsche Telekom SA.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.aai.rest;
22
23 import com.fasterxml.jackson.core.JsonParseException;
24 import com.fasterxml.jackson.databind.JsonMappingException;
25 import com.sun.istack.SAXParseException2;
26
27 import java.util.ArrayList;
28
29 import javax.annotation.Priority;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.ws.rs.WebApplicationException;
32 import javax.ws.rs.core.Context;
33 import javax.ws.rs.core.HttpHeaders;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response;
36 import javax.ws.rs.ext.ExceptionMapper;
37 import javax.ws.rs.ext.Provider;
38
39 import org.janusgraph.core.SchemaViolationException;
40 import org.onap.aai.exceptions.AAIException;
41 import org.onap.aai.logging.ErrorLogHelper;
42
43 /**
44  * The Class ExceptionHandler.
45  */
46 @Provider
47 @Priority(10000)
48 public class ExceptionHandler implements ExceptionMapper<Exception> {
49
50     private static final String AAI_4007 = "AAI_4007";
51
52     @Context
53     private HttpServletRequest request;
54
55     @Context
56     private HttpHeaders headers;
57
58     @Override
59     public Response toResponse(Exception exception) {
60         // the general case is that cxf will give us a WebApplicationException
61         // with a linked exception
62         if (exception instanceof WebApplicationException) {
63             if (exception.getCause() instanceof SAXParseException2) {
64                 return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
65             } else {
66                 return ((WebApplicationException) exception).getResponse();
67             }
68         } else if (exception instanceof JsonParseException) {
69             // jackson does it differently so we get the direct JsonParseException
70             return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
71         } else if (exception instanceof JsonMappingException) {
72             // jackson does it differently so we get the direct JsonParseException
73             return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
74         } else if (exception instanceof SchemaViolationException) {
75             return buildAAIExceptionResponse(new AAIException("AAI_4020", exception));
76         // it didn't get set above, we wrap a general fault here
77         } else if (exception instanceof AAIException) {
78             return buildAAIExceptionResponse((AAIException) exception);
79         } else {
80             return defaultException(exception);
81         }
82     }
83
84     private Response buildAAIExceptionResponse(AAIException exception) {
85         ArrayList<String> templateVars = new ArrayList<>();
86         templateVars.add(request.getMethod());
87         templateVars.add(request.getRequestURI());
88
89         // prefer xml, use json otherwise
90         return headers.getAcceptableMediaTypes().stream()
91             .filter(MediaType.APPLICATION_ATOM_XML_TYPE::isCompatible)
92             .findAny()
93             .map(xmlType -> 
94                 Response.status(400).type(MediaType.APPLICATION_XML_TYPE)
95                     .entity(ErrorLogHelper.getRESTAPIErrorResponse(
96                         headers.getAcceptableMediaTypes(), exception, templateVars))
97                     .build())
98             .orElseGet(() -> 
99                 Response.status(400).type(MediaType.APPLICATION_JSON_TYPE)
100                 .entity(ErrorLogHelper.getRESTAPIErrorResponse(
101                     headers.getAcceptableMediaTypes(), exception, templateVars))
102                 .build());
103     }
104
105     private Response defaultException(Exception exception) {
106         return buildAAIExceptionResponse(new AAIException("AAI_4000", exception));
107     }
108 }