2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.filters;
23 import com.google.gson.GsonBuilder;
24 import org.openecomp.sdc.be.config.BeEcompErrorManager;
25 import org.openecomp.sdc.be.config.Configuration;
26 import org.openecomp.sdc.be.config.ConfigurationManager;
27 import org.openecomp.sdc.be.dao.api.ActionStatus;
28 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
29 import org.openecomp.sdc.be.impl.ComponentsUtils;
30 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
31 import org.openecomp.sdc.common.api.Constants;
32 import org.openecomp.sdc.common.log.elements.LogFieldsMdcHandler;
33 import org.openecomp.sdc.common.log.enums.LogLevel;
34 import org.openecomp.sdc.common.log.enums.Severity;
35 import org.openecomp.sdc.common.log.wrappers.Logger;
36 import org.openecomp.sdc.common.log.wrappers.LoggerSdcAudit;
37 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
38 import org.openecomp.sdc.exception.ResponseFormat;
40 import org.springframework.web.context.WebApplicationContext;
42 import javax.annotation.Priority;
43 import javax.servlet.ServletContext;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.ws.rs.container.ContainerRequestContext;
46 import javax.ws.rs.container.ContainerRequestFilter;
47 import javax.ws.rs.container.ContainerResponseContext;
48 import javax.ws.rs.container.ContainerResponseFilter;
49 import javax.ws.rs.core.Context;
50 import javax.ws.rs.core.Response;
51 import javax.ws.rs.ext.Provider;
52 import java.io.IOException;
53 import java.util.UUID;
57 public class BeServletFilter implements ContainerRequestFilter, ContainerResponseFilter {
60 private HttpServletRequest sr;
61 private static final Logger log = Logger.getLogger(BeServletFilter.class);
62 private static LoggerSdcAudit audit = new LoggerSdcAudit(BeServletFilter.class);
65 public void filter(ContainerRequestContext requestContext) throws IOException {
70 audit.startLog(requestContext);
72 // In case of 405 response code, this function is not entered, then
74 // the MDC fields and UUID during the response
75 ThreadLocalsHolder.setMdcProcessed(true);
77 // Timing HTTP request
78 ThreadLocalsHolder.setRequestStartTime(System.currentTimeMillis());
80 String uuid = processMdcFields(requestContext);
82 ThreadLocalsHolder.setUuid(uuid);
86 } catch (Exception e) {
87 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter");
88 log.debug("Error during request filter: {} ", e);
93 public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
95 // Formatting the response in case of 405
96 if (responseContext.getStatus() == Response.Status.METHOD_NOT_ALLOWED.getStatusCode()) {
97 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_ALLOWED);
98 responseContext.setEntity(new GsonBuilder().setPrettyPrinting().create().toJson(responseFormat.getRequestError()));
101 if (ThreadLocalsHolder.isMdcProcessed()) {
102 // filter() was executed during request - this is the regular
104 responseContext.getHeaders().add(Constants.X_ECOMP_REQUEST_ID_HEADER, ThreadLocalsHolder.getUuid());
105 Long startTime = ThreadLocalsHolder.getRequestStartTime();
106 if (startTime != null) {
107 long endTime = System.currentTimeMillis();
108 MDC.put("timer", Long.toString(endTime - startTime));
111 // this is the 405 response code case
112 // we have no MDC fields since filter() wasn't executed during
114 String uuid = processMdcFields(requestContext);
116 responseContext.getHeaders().add(Constants.X_ECOMP_REQUEST_ID_HEADER, uuid);
117 // call to start-log method to fill mandatory fields
118 audit.startLog(requestContext);
121 writeToTitan(responseContext);
123 //write to Audit log in case it's valuable action
124 // (e.g. ignoring healthCheck and any other unlogged urls as in yaml
126 audit.log(sr.getRemoteAddr(),
128 responseContext.getStatusInfo(),
131 LogFieldsMdcHandler.getInstance()
135 outHttpResponse(responseContext);
137 } catch (Exception e) {
138 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter");
139 log.debug("Error during response filter: {} ", e);
143 ThreadLocalsHolder.cleanup();
147 private void writeToTitan(ContainerResponseContext responseContext) {
148 log.debug("Close transaction from filter");
149 TitanDao titanDao = getTitanDao();
150 if (titanDao != null) {
151 if (responseContext.getStatus() == Response.Status.OK.getStatusCode() ||
152 responseContext.getStatus() == Response.Status.CREATED.getStatusCode()) {
154 log.debug("Doing commit from filter");
157 log.debug("Doing rollback from filter");
162 private String processMdcFields(ContainerRequestContext requestContext) {
163 // UserId for logging
164 String userId = requestContext.getHeaderString(Constants.USER_ID_HEADER);
165 MDC.put("userId", userId);
167 String serviceInstanceID = requestContext.getHeaderString(Constants.X_ECOMP_SERVICE_ID_HEADER);
168 MDC.put("serviceInstanceID", serviceInstanceID);
170 MDC.put("remoteAddr", sr.getRemoteAddr());
171 MDC.put("localAddr", sr.getLocalAddr());
174 String uuid = requestContext.getHeaderString(Constants.X_ECOMP_REQUEST_ID_HEADER);
177 uuid = UUID.randomUUID().toString();
179 // Add to MDC for logging
180 MDC.put("uuid", uuid);
182 // This log message should already be with the UUID
183 uuidGeneration(uuid);
186 // According to Ella, in case this header exists, we don't have to
187 // perform any validations
188 // since it's not our responsibilty, so we log the UUID just as it
190 MDC.put("uuid", uuid);
195 private ComponentsUtils getComponentsUtils() {
196 ServletContext context = this.sr.getSession().getServletContext();
198 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
199 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
200 return webApplicationContext.getBean(ComponentsUtils.class);
203 private TitanDao getTitanDao() {
204 ServletContext context = this.sr.getSession().getServletContext();
206 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
207 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
208 return webApplicationContext.getBean(TitanDao.class);
211 // Extracted for purpose of clear method name, for logback %M parameter
212 private void inHttpRequest() {
214 log.info("{} {} {}", sr.getMethod(), sr.getRequestURI(), sr.getProtocol());
216 log.debug("{} {} {}", sr.getMethod(), sr.getRequestURI(), sr.getProtocol());
220 // Extracted for purpose of clear method name, for logback %M parameter
221 private void outHttpResponse(ContainerResponseContext responseContext) {
223 log.info("{} {} {} SC=\"{}\"", sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), responseContext.getStatus());
225 log.debug("{} {} {} SC=\"{}\"", sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), responseContext.getStatus());
229 private boolean isInfoLog() {
230 boolean logRequest = true;
231 Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
232 String requestURI = sr.getRequestURI();
233 if (requestURI != null && configuration.getUnLoggedUrls() != null) {
234 logRequest = !configuration.getUnLoggedUrls().contains(requestURI);
239 // Extracted for purpose of clear method name, for logback %M parameter
240 private void uuidGeneration(String uuid) {
241 log.info("No requestID provided -> Generated UUID {}", uuid);