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.fe.servlets;
24 import java.util.concurrent.TimeUnit;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
29 import org.eclipse.jetty.client.api.Response;
30 import org.openecomp.sdc.common.api.Constants;
31 import org.openecomp.sdc.common.config.EcompErrorName;
32 import org.openecomp.sdc.fe.config.Configuration;
33 import org.openecomp.sdc.fe.config.ConfigurationManager;
34 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 import com.google.common.cache.Cache;
40 import com.google.common.cache.CacheBuilder;
42 public class FeProxyServlet extends SSLProxyServlet {
43 private static final long serialVersionUID = 1L;
44 private static final String URL = "%s://%s:%s%s";
45 private static Logger log = LoggerFactory.getLogger(FeProxyServlet.class.getName());
46 private static Cache<String, MdcData> mdcDataCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
49 public URI rewriteURI(HttpServletRequest request) {
51 logFeRequest(request);
52 } catch (Exception e) {
53 FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request");
54 log.error("Unexpected FE request logging error :", e);
56 String originalUrl = request.getRequestURL().toString();
57 String redirectedUrl = getModifiedUrl(request);
59 log.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl);
61 return URI.create(redirectedUrl);
65 protected void onResponseSuccess(HttpServletRequest request, HttpServletResponse response, Response proxyResponse) {
67 logFeResponse(request, proxyResponse);
68 } catch (Exception e) {
69 FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response");
70 log.error("Unexpected FE response logging error :", e);
72 super.onResponseSuccess(request, response, proxyResponse);
75 private void logFeRequest(HttpServletRequest httpRequest) {
79 Long transactionStartTime = System.currentTimeMillis();
80 // UUID - In FE, we are supposed to get the below header from UI.
81 // We do not generate it if it's missing - BE does.
82 String uuid = httpRequest.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
83 String serviceInstanceID = httpRequest.getHeader(Constants.X_ECOMP_SERVICE_ID_HEADER);
85 if (uuid != null && uuid.length() > 0) {
87 String userId = httpRequest.getHeader(Constants.USER_ID_HEADER);
89 String remoteAddr = httpRequest.getRemoteAddr();
90 String localAddr = httpRequest.getLocalAddr();
92 mdcDataCache.put(uuid, new MdcData(serviceInstanceID, userId, remoteAddr, localAddr, transactionStartTime));
94 updateMdc(uuid, serviceInstanceID, userId, remoteAddr, localAddr, null);
96 inHttpRequest(httpRequest);
99 private void logFeResponse(HttpServletRequest request, Response proxyResponse) {
100 String uuid = request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
101 String transactionRoundTime = null;
104 MdcData mdcData = mdcDataCache.getIfPresent(uuid);
105 if (mdcData != null) {
106 Long transactionStartTime = mdcData.getTransactionStartTime();
107 if (transactionStartTime != null) {// should'n ever be null, but
108 // just to be defensive
109 transactionRoundTime = Long.toString(System.currentTimeMillis() - transactionStartTime);
111 updateMdc(uuid, mdcData.getServiceInstanceID(), mdcData.getUserId(), mdcData.getRemoteAddr(), mdcData.getLocalAddr(), transactionRoundTime);
114 outHttpResponse(proxyResponse);
119 // Extracted for purpose of clear method name, for logback %M parameter
120 private void inHttpRequest(HttpServletRequest httpRequest) {
121 log.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol());
124 // Extracted for purpose of clear method name, for logback %M parameter
125 private void outHttpResponse(Response proxyResponse) {
126 log.info("SC=\"{}\"", proxyResponse.getStatus());
129 private void updateMdc(String uuid, String serviceInstanceID, String userId, String remoteAddr, String localAddr, String transactionStartTime) {
130 MDC.put("uuid", uuid);
131 MDC.put("serviceInstanceID", serviceInstanceID);
132 MDC.put("userId", userId);
133 MDC.put("remoteAddr", remoteAddr);
134 MDC.put("localAddr", localAddr);
135 MDC.put("timer", transactionStartTime);
138 private class MdcData {
139 private String serviceInstanceID;
140 private String userId;
141 private String remoteAddr;
142 private String localAddr;
143 private Long transactionStartTime;
145 public MdcData(String serviceInstanceID, String userId, String remoteAddr, String localAddr, Long transactionStartTime) {
147 this.serviceInstanceID = serviceInstanceID;
148 this.userId = userId;
149 this.remoteAddr = remoteAddr;
150 this.localAddr = localAddr;
151 this.transactionStartTime = transactionStartTime;
154 public Long getTransactionStartTime() {
155 return transactionStartTime;
158 public String getUserId() {
162 public String getRemoteAddr() {
166 public String getLocalAddr() {
170 public String getServiceInstanceID() {
171 return serviceInstanceID;
175 public String getModifiedUrl(HttpServletRequest request) {
177 Configuration config = getConfiguration(request);
178 if (config == null) {
179 log.error("failed to retrive configuration.");
181 String scheme = config.getBeProtocol();
182 String uri = request.getRequestURI().toString();
183 StringBuilder url = new StringBuilder();
184 url.append(scheme).append("://").append(config.getBeHost());
186 if (config.getBeProtocol().equals(BE_PROTOCOL.HTTP.getProtocolName())) {
187 url.append(config.getBeHttpPort());
189 url.append(config.getBeSslPort());
192 String queryString = request.getQueryString(); // d=789
193 if (queryString != null) {
194 url.append("?").append(queryString);
197 String redirectedUrl = url.toString();
198 String onboardingForwardContext = config.getOnboardingForwardContext();
199 if (onboardingForwardContext == null || onboardingForwardContext.isEmpty()) {
200 onboardingForwardContext = "/onboarding-api";
202 redirectedUrl = redirectedUrl.replace("/sdc1/feProxy/dcae-api", "/dcae");
203 redirectedUrl = redirectedUrl.replace("/sdc1/feProxy/onboarding-api", onboardingForwardContext);
204 redirectedUrl = redirectedUrl.replace("/sdc1/feProxy", "/sdc2");
205 return redirectedUrl;
209 private Configuration getConfiguration(HttpServletRequest request) {
210 Configuration config = ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getConfiguration();