Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / filters / BeServletFilter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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.openecomp.sdc.be.filters;
22
23 import com.google.gson.GsonBuilder;
24 import org.onap.logging.filter.base.AuditLogContainerFilter;
25 import org.onap.logging.ref.slf4j.ONAPLogConstants;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.config.Configuration;
28 import org.openecomp.sdc.be.config.ConfigurationManager;
29 import org.openecomp.sdc.be.dao.api.ActionStatus;
30 import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao;
31 import org.openecomp.sdc.be.impl.ComponentsUtils;
32 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
33 import org.openecomp.sdc.common.api.Constants;
34 import org.openecomp.sdc.common.log.api.ILogConfiguration;
35 import org.openecomp.sdc.common.log.enums.Severity;
36 import org.openecomp.sdc.common.log.wrappers.Logger;
37 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
38 import org.openecomp.sdc.exception.ResponseFormat;
39 import org.slf4j.MDC;
40 import org.springframework.web.context.WebApplicationContext;
41
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.ContainerResponseContext;
47 import javax.ws.rs.core.Context;
48 import javax.ws.rs.core.Response;
49 import javax.ws.rs.ext.Provider;
50 import java.io.IOException;
51
52 @Provider
53 @Priority(1)
54 public class BeServletFilter extends AuditLogContainerFilter {
55
56     @Context
57     private HttpServletRequest sr;
58     private static final Logger log = Logger.getLogger(BeServletFilter.class);
59
60     @Override
61     public void filter(ContainerRequestContext requestContext) {
62         if (isLoggedRequest()) {
63             try {
64                 super.filter(requestContext);
65                 // In case of 405 response code, this function is not entered, then
66                 // we'll process
67                 // the MDC fields and UUID during the response
68                 ThreadLocalsHolder.setMdcProcessed(true);
69                 // Timing HTTP request
70                 ThreadLocalsHolder.setRequestStartTime(System.currentTimeMillis());
71                 processMdcFields(requestContext);
72                 ThreadLocalsHolder.setUuid(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
73                 inHttpRequest();
74             } catch (Exception e) {
75                 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter");
76                 log.debug("Error during request filter: {} ", e);
77             }
78         }
79     }
80
81     @Override
82     protected void additionalPreHandling(ContainerRequestContext containerRequestContext) {
83         MDC.put(ILogConfiguration.MDC_REMOTE_HOST, sr.getRemoteAddr());
84         MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, containerRequestContext.getHeaderString(Constants.X_ECOMP_SERVICE_ID_HEADER));
85         MDC.put(ONAPLogConstants.MDCs.RESPONSE_SEVERITY, String.valueOf(Severity.OK.getSeverityType()));
86     }
87
88     @Override
89     public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
90         if (isLoggedRequest()) {
91             try {
92                 super.filter(requestContext, responseContext);
93                 // Formatting the response in case of 405
94                 if (responseContext.getStatus() == Response.Status.METHOD_NOT_ALLOWED.getStatusCode()) {
95                     ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_ALLOWED);
96                     responseContext.setEntity(new GsonBuilder().setPrettyPrinting().create().toJson(responseFormat.getRequestError()));
97                 }
98
99                 if (ThreadLocalsHolder.isMdcProcessed()) {
100                     // filter() was executed during request - this is the regular
101                     // flow
102                     responseContext.getHeaders().add(Constants.X_ECOMP_REQUEST_ID_HEADER, ThreadLocalsHolder.getUuid());
103                 }
104                 writeToJanusGraph(responseContext);
105
106                 outHttpResponse(responseContext);
107
108             } catch (Exception e) {
109                 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter");
110                 log.debug("Error during response filter: {} ", e);
111             } finally {
112                 // Cleaning up
113                 MDC.clear();
114                 ThreadLocalsHolder.cleanup();
115             }
116         }
117     }
118
119     private void writeToJanusGraph(ContainerResponseContext responseContext) {
120         log.debug("Close transaction from filter");
121         HealingJanusGraphDao janusGraphDao = getJanusGraphDao();
122         if (janusGraphDao != null) {
123             int status = responseContext.getStatus();
124             if (status == Response.Status.OK.getStatusCode() ||
125                     status == Response.Status.CREATED.getStatusCode() ||
126                     status == Response.Status.NO_CONTENT.getStatusCode()) {
127                 janusGraphDao.commit();
128                 log.debug("Doing commit from filter");
129             } else {
130                 janusGraphDao.rollback();
131                 log.debug("Doing rollback from filter");
132             }
133         }
134     }
135
136     private void processMdcFields(ContainerRequestContext requestContext) {
137         // UserId for logging
138         String userId = requestContext.getHeaderString(Constants.USER_ID_HEADER);
139         MDC.put("userId", userId);
140
141         String serviceInstanceID = requestContext.getHeaderString(Constants.X_ECOMP_SERVICE_ID_HEADER);
142         MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, serviceInstanceID);
143
144         MDC.put("remoteAddr", sr.getRemoteAddr());
145         MDC.put("localAddr", sr.getLocalAddr());
146     }
147
148     private ComponentsUtils getComponentsUtils() {
149         ServletContext context = this.sr.getSession().getServletContext();
150
151         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
152         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
153         return webApplicationContext.getBean(ComponentsUtils.class);
154     }
155
156     private HealingJanusGraphDao getJanusGraphDao() {
157         ServletContext context = this.sr.getSession().getServletContext();
158
159         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
160         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
161         return webApplicationContext.getBean(HealingJanusGraphDao.class);
162     }
163
164     // Extracted for purpose of clear method name, for logback %M parameter
165     private void inHttpRequest() {
166         log.info("{} {} {}", sr.getMethod(), sr.getRequestURI(), sr.getProtocol());
167     }
168
169     // Extracted for purpose of clear method name, for logback %M parameter
170     private void outHttpResponse(ContainerResponseContext responseContext) {
171         log.info("{} {} {} SC=\"{}\"", sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), responseContext.getStatus());
172     }
173
174     private boolean isLoggedRequest() {
175         boolean logRequest = true;
176         Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
177         String requestURI = sr.getRequestURI();
178         if (requestURI != null && configuration.getUnLoggedUrls() != null) {
179             logRequest = !configuration.getUnLoggedUrls().contains(requestURI);
180         }
181         return logRequest;
182     }
183 }