Update the SO release notes
[so.git] / mso-api-handlers / mso-api-handler-common / src / main / java / org / onap / so / apihandlerinfra / exceptions / ApiExceptionMapper.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.apihandlerinfra.exceptions;
22
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
28
29 import javax.ws.rs.core.Context;
30 import javax.ws.rs.core.HttpHeaders;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
33 import javax.ws.rs.ext.ExceptionMapper;
34 import javax.ws.rs.ext.Provider;
35 import javax.xml.bind.JAXBContext;
36 import javax.xml.bind.JAXBException;
37 import javax.xml.bind.Marshaller;
38
39 import org.onap.so.apihandlerinfra.logging.AlarmLoggerInfo;
40 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
41 import org.onap.so.logger.MessageEnum;
42 import org.onap.so.logger.MsoAlarmLogger;
43 import org.onap.so.logger.MsoLogger;
44 import org.onap.so.serviceinstancebeans.RequestError;
45 import org.onap.so.serviceinstancebeans.ServiceException;
46
47 import com.fasterxml.jackson.annotation.JsonInclude;
48 import com.fasterxml.jackson.core.JsonProcessingException;
49 import com.fasterxml.jackson.databind.ObjectMapper;
50 import com.fasterxml.jackson.databind.SerializationFeature;
51
52 @Provider
53 public class ApiExceptionMapper implements ExceptionMapper<ApiException> {
54
55     private static MsoLogger logger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA, ApiExceptionMapper.class);
56     private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
57     
58     private final JAXBContext context;
59     private final Marshaller marshaller;
60
61     @Context
62     private HttpHeaders headers;
63
64     public ApiExceptionMapper() {
65         try {
66                         context = JAXBContext.newInstance(RequestError.class);
67                 marshaller = context.createMarshaller();
68                 } catch (JAXBException e) {
69                         logger.debug("could not create JAXB marshaller");
70                         throw new IllegalStateException(e);
71                 }
72     }
73     @Override
74     public Response toResponse(ApiException exception) {
75
76         return Response.status(exception.getHttpResponseCode()).entity(buildErrorString(exception)).build();
77     }
78
79     protected String buildErrorString(ApiException exception) {
80         String errorText = exception.getMessage();
81         String messageId = exception.getMessageID();
82         List<String> variables = exception.getVariables();
83         ErrorLoggerInfo errorLoggerInfo = exception.getErrorLoggerInfo();
84         AlarmLoggerInfo alarmLoggerInfo = exception.getAlarmLoggerInfo();
85
86
87         if (errorText.length() > 1999) {
88             errorText = errorText.substring(0, 1999);
89         }
90
91         writeErrorLog(exception, errorText, errorLoggerInfo, alarmLoggerInfo);
92         
93         List<MediaType> typeList = Optional.ofNullable(headers.getAcceptableMediaTypes()).orElse(new ArrayList<>());
94         List<String> typeListString = typeList.stream().map(item -> item.toString()).collect(Collectors.toList());
95         MediaType type;
96         if (typeListString.stream().anyMatch(item -> item.contains(MediaType.APPLICATION_XML))) {
97                 type = MediaType.APPLICATION_XML_TYPE;
98         } else if (typeListString.stream().anyMatch(item -> typeListString.contains(MediaType.APPLICATION_JSON))) {
99                 type = MediaType.APPLICATION_JSON_TYPE;
100         } else {
101                 type = MediaType.APPLICATION_JSON_TYPE;
102         }
103
104         return buildServiceErrorResponse(errorText,messageId,variables, type);
105
106     }
107
108     protected String buildServiceErrorResponse(String errorText, String messageId, List<String> variables, MediaType type){
109         RequestError re = new RequestError();
110         ServiceException se = new ServiceException();
111         se.setMessageId(messageId);
112         se.setText(errorText);
113         if (variables != null) {
114             for (String variable : variables) {
115                 se.getVariables().add(variable);
116             }
117         }
118         re.setServiceException(se);
119         String requestErrorStr;
120
121         ObjectMapper mapper = createObjectMapper();
122         
123         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
124         mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
125         try {
126                 if (MediaType.APPLICATION_JSON_TYPE.equals(type)) {
127                         requestErrorStr = mapper.writeValueAsString(re);
128             } else {
129                 StringWriter sw = new StringWriter();
130                 this.getMarshaller().marshal(re, sw);
131                 requestErrorStr = sw.toString();
132             }
133         } catch (JsonProcessingException | JAXBException e) {
134             String errorMsg = "Exception in buildServiceErrorResponse writing exceptionType to string " + e.getMessage();
135             logger.error(MessageEnum.GENERAL_EXCEPTION, "BuildServiceErrorResponse", "", "", MsoLogger.ErrorCode.DataError, errorMsg, e);
136             return errorMsg;
137         }
138
139         return requestErrorStr;
140     }
141
142     protected void writeErrorLog(Exception e, String errorText, ErrorLoggerInfo errorLogInfo, AlarmLoggerInfo alarmLogInfo) {
143         if( e!= null)
144             logger.error(e);
145         if(errorLogInfo != null)
146             logger.error(errorLogInfo.getLoggerMessageType().toString(), errorLogInfo.getErrorSource(), errorLogInfo.getTargetEntity(), errorLogInfo.getTargetServiceName(), errorLogInfo.getErrorCode(), errorText);
147         if(alarmLogInfo != null){
148             alarmLogger.sendAlarm(alarmLogInfo.getAlarm(),alarmLogInfo.getState(),alarmLogInfo.getDetail());
149         }
150     }
151
152     public ObjectMapper createObjectMapper(){
153         return new ObjectMapper();
154     }
155     
156     public Marshaller getMarshaller() {
157         return marshaller;
158     }
159     
160 }