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