a467a9e38a151cd59797b4035381becb35186a0c
[sdc.git] / openecomp-be / lib / openecomp-sdc-logging-lib / openecomp-sdc-logging-spring / src / main / java / org / openecomp / sdc / logging / servlet / spring / LoggingInterceptor.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.logging.servlet.spring;
18
19 import static org.openecomp.sdc.logging.api.StatusCode.COMPLETE;
20 import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
21
22 import java.util.Objects;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25 import org.openecomp.sdc.logging.api.Logger;
26 import org.openecomp.sdc.logging.api.LoggerFactory;
27 import org.openecomp.sdc.logging.api.StatusCode;
28 import org.openecomp.sdc.logging.servlet.CombinedTracker;
29 import org.openecomp.sdc.logging.servlet.HttpHeader;
30 import org.openecomp.sdc.logging.servlet.RequestProcessingResult;
31 import org.openecomp.sdc.logging.servlet.Tracker;
32 import org.springframework.http.HttpStatus;
33 import org.springframework.web.method.HandlerMethod;
34 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
35
36 /**
37  * <p>IMPORTANT: For this interceptor to work, all exceptions must be properly handled before being returned to a
38  * client. Any unexpected, automatically handled exception bypasses the interceptor and will not be logged.</p>
39  * <p>The interceptor must be either registered in Spring configuration XML as a bean, or programmatically as described
40  * in <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-config-interceptors">
41  * Spring MVC Config: Interceptors</a>.</p>
42  *
43  * @author evitaliy
44  * @since 02 Aug 2018
45  */
46 public class LoggingInterceptor extends HandlerInterceptorAdapter {
47
48     static final String LOGGING_TRACKER_KEY = "onap.logging.tracker";
49
50     private static final Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
51
52     private final HttpHeader partnerNameHeader;
53     private final HttpHeader requestIdHeader;
54
55     public LoggingInterceptor(HttpHeader partnerNameHeader, HttpHeader requestIdHeader) {
56         this.partnerNameHeader = Objects.requireNonNull(partnerNameHeader);
57         this.requestIdHeader = Objects.requireNonNull(requestIdHeader);
58     }
59
60     @Override
61     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
62         Class<?> resourceClass = getResourceType(handler);
63         Tracker tracker = new CombinedTracker(resourceClass, partnerNameHeader, requestIdHeader);
64         request.setAttribute(LOGGING_TRACKER_KEY, tracker);
65         tracker.preRequest(request);
66         return true;
67     }
68
69     @Override
70     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
71             Exception ex) {
72
73         Tracker tracker = (Tracker) request.getAttribute(LOGGING_TRACKER_KEY);
74
75         if (tracker == null) {
76             LOGGER.debug("No logging tracker received");
77             return;
78         }
79
80         tracker.postRequest(new ServletResponseResult(response.getStatus()));
81     }
82
83     private Class<?> getResourceType(Object handler) {
84
85         if (handler instanceof HandlerMethod) {
86             return ((HandlerMethod) handler).getMethod().getDeclaringClass();
87         }
88
89         return LoggingInterceptor.class;
90     }
91
92     static class ServletResponseResult implements RequestProcessingResult {
93
94         private final HttpStatus status;
95
96         ServletResponseResult(int status) {
97             this.status = HttpStatus.valueOf(status);
98         }
99
100         @Override
101         public int getStatus() {
102             return status.value();
103         }
104
105         @Override
106         public StatusCode getStatusCode() {
107             return status.is2xxSuccessful() || status.is3xxRedirection() ? COMPLETE : ERROR;
108         }
109
110         @Override
111         public String getStatusPhrase() {
112             return status.getReasonPhrase();
113         }
114     }
115 }