re base code
[sdc.git] / catalog-fe / src / main / java / org / openecomp / sdc / fe / servlets / FeProxyServlet.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.fe.servlets;
22
23 import com.google.common.cache.Cache;
24 import com.google.common.cache.CacheBuilder;
25 import org.eclipse.jetty.client.api.Response;
26 import org.openecomp.sdc.common.api.Constants;
27 import org.openecomp.sdc.fe.config.Configuration;
28 import org.openecomp.sdc.fe.config.ConfigurationManager;
29 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
30 import org.openecomp.sdc.fe.impl.MdcData;
31 import org.openecomp.sdc.fe.utils.BeProtocol;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.slf4j.MDC;
35
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38 import java.util.concurrent.TimeUnit;
39
40 public class FeProxyServlet extends SSLProxyServlet {
41         private static final long serialVersionUID = 1L;
42         private static final String URL = "%s://%s%s%s";
43         private static final String ONBOARDING_CONTEXT = "/onboarding-api";
44         private static final String DCAED_CONTEXT = "/dcae-api";
45         private static final Logger log = LoggerFactory.getLogger(FeProxyServlet.class.getName());
46         private static Cache<String, MdcData> mdcDataCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
47
48
49         @Override
50         protected String rewriteTarget(HttpServletRequest request) {
51                 try {
52                         logFeRequest(request);
53                 } catch (Exception e) {
54                         FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request");
55                         log.error("Unexpected FE request logging error :", e);
56                 }
57                 String originalUrl = request.getRequestURL().toString();
58                 String redirectedUrl = getModifiedUrl(request);
59
60                 log.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl);
61
62                 return redirectedUrl;
63         }
64
65         @Override
66         protected void onProxyResponseSuccess(HttpServletRequest request, HttpServletResponse proxyResponse, Response response) {
67                 try {
68                         logFeResponse(request, response);
69                 } catch (Exception e) {
70                         FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response");
71                         log.error("Unexpected FE response logging error :", e);
72                 }
73                 super.onProxyResponseSuccess(request, proxyResponse, response);
74         }
75
76         private void logFeRequest(HttpServletRequest httpRequest) {
77
78                 MDC.clear();
79
80                 Long transactionStartTime = System.currentTimeMillis();
81                 // UUID - In FE, we are supposed to get the below header from UI.
82                 // We do not generate it if it's missing - BE does.
83                 String uuid = httpRequest.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
84                 String serviceInstanceID = httpRequest.getHeader(Constants.X_ECOMP_SERVICE_ID_HEADER);
85
86                 if (uuid != null && uuid.length() > 0) {
87                         // UserId for logging
88                         String userId = httpRequest.getHeader(Constants.USER_ID_HEADER);
89
90                         String remoteAddr = httpRequest.getRemoteAddr();
91                         String localAddr = httpRequest.getLocalAddr();
92
93                         mdcDataCache.put(uuid, new MdcData(serviceInstanceID, userId, remoteAddr, localAddr, transactionStartTime));
94
95                         updateMdc(uuid, serviceInstanceID, userId, remoteAddr, localAddr, null);
96                 }
97                 inHttpRequest(httpRequest);
98         }
99
100         private void logFeResponse(HttpServletRequest request, Response proxyResponse) {
101                 String uuid = request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
102                 String transactionRoundTime = null;
103
104                 if (uuid != null) {
105                         MdcData mdcData = mdcDataCache.getIfPresent(uuid);
106                         if (mdcData != null) {
107                                 Long transactionStartTime = mdcData.getTransactionStartTime();
108                                 if (transactionStartTime != null) {// should'n ever be null, but
109                                         // just to be defensive
110                                         transactionRoundTime = Long.toString(System.currentTimeMillis() - transactionStartTime);
111                                 }
112                                 updateMdc(uuid, mdcData.getServiceInstanceID(), mdcData.getUserId(), mdcData.getRemoteAddr(), mdcData.getLocalAddr(), transactionRoundTime);
113                         }
114                 }
115                 outHttpResponse(proxyResponse);
116
117                 MDC.clear();
118         }
119
120         // Extracted for purpose of clear method name, for logback %M parameter
121         private void inHttpRequest(HttpServletRequest httpRequest) {
122                 log.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol());
123         }
124
125         // Extracted for purpose of clear method name, for logback %M parameter
126         private void outHttpResponse(Response proxyResponse) {
127                 log.info("SC=\"{}\"", proxyResponse.getStatus());
128         }
129
130         private void updateMdc(String uuid, String serviceInstanceID, String userId, String remoteAddr, String localAddr, String transactionStartTime) {
131                 MDC.put("uuid", uuid);
132                 MDC.put("serviceInstanceID", serviceInstanceID);
133                 MDC.put("userId", userId);
134                 MDC.put("remoteAddr", remoteAddr);
135                 MDC.put("localAddr", localAddr);
136                 MDC.put("timer", transactionStartTime);
137         }
138
139         
140         
141         private String getModifiedUrl(HttpServletRequest request) {
142                 Configuration config = getConfiguration(request);
143                 if (config == null) {
144                         log.error("failed to retrive configuration.");
145                         throw new RuntimeException("failed to read FE configuration");
146                 }
147                 String uri = request.getRequestURI();
148                 String protocol;
149                 String host;
150                 String port;
151                 if (uri.contains(ONBOARDING_CONTEXT)){
152                         uri = uri.replace("/sdc1/feProxy"+ONBOARDING_CONTEXT,ONBOARDING_CONTEXT);
153                         protocol = config.getOnboarding().getProtocolBe();
154                         host = config.getOnboarding().getHostBe();
155                         port = config.getOnboarding().getPortBe().toString();           
156                 }else if(uri.contains(DCAED_CONTEXT)){
157                         uri = uri.replace("/sdc1/feProxy"+DCAED_CONTEXT,DCAED_CONTEXT);
158                         protocol = config.getBeProtocol();
159                         host = config.getBeHost();
160                         if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) {
161                                 port = config.getBeHttpPort().toString();
162                         } else {
163                                 port = config.getBeSslPort().toString();
164                         }
165                 }
166                 else{
167                         uri = uri.replace("/sdc1/feProxy","/sdc2");
168                         protocol = config.getBeProtocol();
169                         host = config.getBeHost();
170                         if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) {
171                                 port = config.getBeHttpPort().toString();
172                         } else {
173                                 port = config.getBeSslPort().toString();
174                         }
175                 }       
176
177                 String authority = getAuthority(host, port);
178                 String queryString = getQueryString(request);
179                 return  String.format(URL,protocol,authority,uri,queryString);
180
181         }
182
183
184
185
186
187
188         private Configuration getConfiguration(HttpServletRequest request) {
189                 return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getConfiguration();
190         }
191
192         private String getAuthority(String host, String port) {
193                 String authority;
194                 if (port==null){
195                         authority=host;
196                 }
197                 else{
198                         authority=host+":"+port;
199                 }
200                 return authority;
201         }
202
203         private String getQueryString(HttpServletRequest request) {
204                 String queryString = request.getQueryString();
205                 if (queryString != null) {
206                         queryString="?"+queryString;
207                 }
208                 else{
209                         queryString="";
210                 }
211                 return queryString;
212         }
213 }