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;
23 import com.google.common.annotations.VisibleForTesting;
24 import org.apache.commons.lang3.NotImplementedException;
25 import org.apache.commons.lang3.StringUtils;
26 import org.eclipse.jetty.client.api.Response;
27 import org.openecomp.sdc.common.api.Constants;
28 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
29 import org.openecomp.sdc.common.log.wrappers.Logger;
30 import org.openecomp.sdc.fe.config.Configuration;
31 import org.openecomp.sdc.fe.config.Configuration.CatalogFacadeMsConfig;
32 import org.openecomp.sdc.fe.config.ConfigurationManager;
33 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
34 import org.openecomp.sdc.fe.config.PluginsConfiguration;
35 import org.openecomp.sdc.fe.config.PluginsConfiguration.Plugin;
36 import org.openecomp.sdc.fe.impl.LogHandler;
37 import org.openecomp.sdc.fe.utils.BeProtocol;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
41 import java.net.MalformedURLException;
44 import static org.apache.commons.lang3.StringUtils.isEmpty;
47 public class FeProxyServlet extends SSLProxyServlet {
48 private static final long serialVersionUID = 1L;
49 private static final String URL = "%s://%s%s";
50 private static final String MS_URL = "%s://%s:%s";
51 private static final String ONBOARDING_CONTEXT = "/onboarding-api";
52 private static final String DCAED_CONTEXT = "/dcae-api";
53 private static final String WORKFLOW_CONTEXT = "/wf";
54 private static final String SDC1_FE_PROXY = "/sdc1/feProxy";
55 private static final String PLUGIN_ID_WORKFLOW = "WORKFLOW";
56 public static final String UUID = "uuid";
57 public static final String TRANSACTION_START_TIME = "transactionStartTime";
58 private static Logger log = Logger.getLogger(FeProxyServlet.class.getName());
60 private static String msUrl;
61 private static final String FACADE_PATH_IDENTIFIER = "uicache";
62 private static final String CATALOG_REQUEST_IDENTIFIER = "/v1/catalog";
63 private static final String ARCHIVE_PATH_IDENTIFIER = String.format("%s/archive/", CATALOG_REQUEST_IDENTIFIER);
64 private static final String HOME_REQUEST_IDENTIFIER = "/v1/followed";
66 protected String rewriteTarget(HttpServletRequest request) {
67 String originalUrl="";
68 String redirectedUrl = "";
71 logFeRequest(request);
72 originalUrl = request.getRequestURL().toString();
74 Configuration config = getConfiguration(request);
76 log.error("failed to retrieve configuration.");
78 if (isMsRequest(request.getRequestURL().toString())) {
79 redirectedUrl = redirectMsRequestToMservice(request, config);
81 redirectedUrl = getModifiedUrl(config, getPluginConfiguration(request), request.getRequestURI(), getQueryString(request));
84 catch (MalformedURLException mue) {
85 FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request");
86 log.error(EcompLoggerErrorCode.DATA_ERROR, "FeProxyServlet rewriteTarget", "sdc-FE", "Malformed URL Exception: ", mue);
89 log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet rewriteTarget", "sdc-FE", "Unexpected FE request processing error: ", e);
91 if (log.isDebugEnabled()) {
92 log.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl);
99 protected void onProxyResponseSuccess(HttpServletRequest request, HttpServletResponse proxyResponse, Response response) {
101 logFeResponse(request, response);
102 } catch (Exception e) {
103 FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response");
104 log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet onProxyResponseSuccess", "sdc-FE", "Unexpected FE response logging error: ", e);
106 super.onProxyResponseSuccess(request, proxyResponse, response);
109 private void logFeRequest(HttpServletRequest httpRequest){
110 LogHandler.logFeRequest(httpRequest);
111 inHttpRequest(httpRequest);
114 private void logFeResponse(HttpServletRequest request, Response proxyResponse){
115 LogHandler.logFeResponse(request);
116 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 String getModifiedUrl(Configuration config, PluginsConfiguration pluginConf, String uri, String queryString) throws MalformedURLException{
130 if (config == null) {
131 log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet getModifiedUrl", "sdc-FE", "failed to retrieve configuration.");
132 throw new RuntimeException("failed to read FE configuration");
137 if (uri.contains(ONBOARDING_CONTEXT)){
138 uri = uri.replace(SDC1_FE_PROXY+ONBOARDING_CONTEXT,ONBOARDING_CONTEXT);
139 protocol = config.getOnboarding().getProtocolBe();
140 host = config.getOnboarding().getHostBe();
141 port = config.getOnboarding().getPortBe().toString();
142 }else if(uri.contains(DCAED_CONTEXT)){
143 uri = uri.replace(SDC1_FE_PROXY+DCAED_CONTEXT,DCAED_CONTEXT);
144 protocol = config.getBeProtocol();
145 host = config.getBeHost();
146 if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) {
147 port = config.getBeHttpPort().toString();
149 port = config.getBeSslPort().toString();
152 else if (uri.contains(WORKFLOW_CONTEXT)){
153 uri = uri.replace(SDC1_FE_PROXY +WORKFLOW_CONTEXT,WORKFLOW_CONTEXT);
154 String workflowPluginURL = pluginConf.getPluginsList()
156 .filter(plugin -> plugin.getPluginId().equalsIgnoreCase(PLUGIN_ID_WORKFLOW))
157 .map(Plugin::getPluginDiscoveryUrl)
158 .findFirst().orElse(null);
160 java.net.URL workflowURL = new URL(workflowPluginURL);
161 protocol = workflowURL.getProtocol();
162 host = workflowURL.getHost();
163 port = String.valueOf(workflowURL.getPort());
166 uri = uri.replace(SDC1_FE_PROXY,"/sdc2");
167 protocol = config.getBeProtocol();
168 host = config.getBeHost();
169 if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) {
170 port = config.getBeHttpPort().toString();
172 port = config.getBeSslPort().toString();
176 String authority = getAuthority(host, port);
177 String modifiedUrl = String.format(URL,protocol,authority,uri);
178 if( !StringUtils.isEmpty(queryString)){
179 modifiedUrl += "?" + queryString;
186 String redirectMsRequestToMservice(HttpServletRequest request, Configuration config) throws MalformedURLException {
188 boolean isMsToggledOn = isMsToggleOn(config);
189 String redirectValue;
191 redirectValue = handleMsToggleOnRedirect(request, config);
193 redirectValue = handleMsToggleOffRedirect(request, config);
195 return redirectValue;
197 private PluginsConfiguration getPluginConfiguration(HttpServletRequest request) {
198 return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getPluginsConfiguration();
200 private boolean isMsToggleOn(Configuration config) {
201 boolean toggleOn = true;
202 final CatalogFacadeMsConfig catalogFacadeMs = config.getCatalogFacadeMs();
203 if (catalogFacadeMs == null) {
206 } else if (isEmpty(catalogFacadeMs.getHealthCheckUri())) {
208 } else if (isEmpty(catalogFacadeMs.getHost())) {
210 } else if (isEmpty(catalogFacadeMs.getPath())) {
212 } else if (isEmpty(catalogFacadeMs.getProtocol())) {
214 } else if (catalogFacadeMs.getPort() == null) {
219 private String handleMsToggleOffRedirect(HttpServletRequest request, Configuration config) throws MalformedURLException {
220 String redirectValue;
221 String currentURI = request.getRequestURI();
222 if (isEmpty(request.getQueryString())) {
224 if (currentURI.endsWith(CATALOG_REQUEST_IDENTIFIER)) {
225 String facadeSuffix = String.format("%s%s", FACADE_PATH_IDENTIFIER, CATALOG_REQUEST_IDENTIFIER);
226 String nonFacadeUrl = currentURI.replace(facadeSuffix, "rest/v1/screen");
227 redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, "excludeTypes=VFCMT&excludeTypes=Configuration");
230 else if (currentURI.endsWith(HOME_REQUEST_IDENTIFIER)){
231 redirectValue = getModifiedUrl(config, getPluginConfiguration(request), currentURI, getQueryString(request));
234 else if (currentURI.endsWith(ARCHIVE_PATH_IDENTIFIER)) {
235 redirectValue = getModifiedUrl(config, getPluginConfiguration(request), currentURI, getQueryString(request));
237 String message = String.format("facade is toggled off, Could not rediret url %s", currentURI);
239 throw new NotImplementedException(message);
243 if (currentURI.contains("/latestversion/notabstract/metadata")) {
244 String nonFacadeUrl = currentURI.replace(FACADE_PATH_IDENTIFIER, "rest");
245 redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, getQueryString(request));
247 // Catalog with Query Params
248 else if (currentURI.endsWith(CATALOG_REQUEST_IDENTIFIER)) {
249 String facadeSuffix = String.format("%s%s", FACADE_PATH_IDENTIFIER, CATALOG_REQUEST_IDENTIFIER);
250 String nonFacadeUrl = currentURI.replace(facadeSuffix, "rest/v1/screen");
251 redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, "excludeTypes=VFCMT&excludeTypes=Configuration");
253 String message = String.format("facade is toggled off, Could not rediret url %s with query params %s",
254 currentURI, getQueryString(request));
256 throw new NotImplementedException(message);
260 return redirectValue;
263 private String handleMsToggleOnRedirect(HttpServletRequest request, Configuration config) {
264 String currentUrl = request.getRequestURL()
266 if (StringUtils.isEmpty(msUrl)) {
268 msUrl = String.format(MS_URL, config.getCatalogFacadeMs()
270 config.getCatalogFacadeMs().getHost(),
271 config.getCatalogFacadeMs().getPort());
275 String msPath = config.getCatalogFacadeMs().getPath();
276 if (currentUrl.endsWith(ARCHIVE_PATH_IDENTIFIER)) {
277 url = new StringBuilder(msUrl + msPath + CATALOG_REQUEST_IDENTIFIER);
278 queryString = "arc=true";
280 url = new StringBuilder(msUrl + currentUrl.substring(currentUrl.indexOf(msPath)));
281 queryString = request.getQueryString();
283 if (queryString != null) {
284 url.append("?").append(queryString);
286 if (log.isDebugEnabled()) {
287 log.debug("Redirect catalog request to {}", url.toString());
289 return url.toString();
293 boolean isMsRequest(String currentUrl) {
294 return currentUrl.contains(FACADE_PATH_IDENTIFIER) || currentUrl.endsWith(ARCHIVE_PATH_IDENTIFIER);
296 private Configuration getConfiguration(HttpServletRequest request) {
297 return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getConfiguration();
300 private String getAuthority(String host, String port) {
306 authority=host+":"+port;
311 private String getQueryString(HttpServletRequest request){
312 final String queryString = request.getQueryString();
313 return StringUtils.isEmpty(queryString) ? StringUtils.EMPTY : queryString;