Fix 404 in sdc-FE calls to workflow
[sdc.git] / catalog-fe / src / main / java / org / openecomp / sdc / fe / servlets / FeProxyServlet.java
index 0540fad..8f76cb9 100644 (file)
 
 package org.openecomp.sdc.fe.servlets;
 
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import java.net.MalformedURLException;
-import java.net.URL;
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jetty.client.api.Response;
 import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
+import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.fe.config.Configuration;
+import org.openecomp.sdc.fe.config.Configuration.CatalogFacadeMsConfig;
 import org.openecomp.sdc.fe.config.ConfigurationManager;
 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
 import org.openecomp.sdc.fe.config.PluginsConfiguration;
 import org.openecomp.sdc.fe.config.PluginsConfiguration.Plugin;
-import org.openecomp.sdc.fe.impl.MdcData;
+import org.openecomp.sdc.fe.impl.LogHandler;
 import org.openecomp.sdc.fe.utils.BeProtocol;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.concurrent.TimeUnit;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import static org.apache.commons.lang3.StringUtils.isEmpty;
+
 
 public class FeProxyServlet extends SSLProxyServlet {
        private static final long serialVersionUID = 1L;
        private static final String URL = "%s://%s%s%s";
+       private static final String MS_URL = "%s://%s:%s";
        private static final String ONBOARDING_CONTEXT = "/onboarding-api";
        private static final String DCAED_CONTEXT = "/dcae-api";
        private static final String WORKFLOW_CONTEXT = "/wf";
        private static final String SDC1_FE_PROXY = "/sdc1/feProxy";
        private static final String PLUGIN_ID_WORKFLOW = "WORKFLOW";
-
-       private static final Logger log = LoggerFactory.getLogger(FeProxyServlet.class.getName());
-       private static Cache<String, MdcData> mdcDataCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();
-
-
+       public static final String UUID = "uuid";
+       public static final String TRANSACTION_START_TIME = "transactionStartTime";
+       private static Logger log = Logger.getLogger(FeProxyServlet.class.getName());
+
+       private static String msUrl;
+       private static final String FACADE_PATH_IDENTIFIER = "uicache";
+       private static final String CATALOG_REQUEST_IDENTIFIER = "/v1/catalog";
+       private static final String ARCHIVE_PATH_IDENTIFIER = String.format("%s/archive/", CATALOG_REQUEST_IDENTIFIER);
+       private static final String HOME_REQUEST_IDENTIFIER = "/v1/followed";
        @Override
        protected String rewriteTarget(HttpServletRequest request) {
                String originalUrl="";
@@ -61,20 +69,28 @@ public class FeProxyServlet extends SSLProxyServlet {
 
                try {
                        logFeRequest(request);
-
                        originalUrl = request.getRequestURL().toString();
-                       redirectedUrl = getModifiedUrl(request);
 
-               } catch(MalformedURLException mue){
+                       Configuration config = getConfiguration(request);
+                       if (config == null) {
+                               log.error("failed to retrieve configuration.");
+                       }
+                       if (isMsRequest(request.getRequestURL().toString())) {
+                               redirectedUrl = redirectMsRequestToMservice(request, config);
+                       } else {
+                               redirectedUrl = getModifiedUrl(config, getPluginConfiguration(request), request.getRequestURI(), getQueryString(request));
+                       }
+               }
+               catch (MalformedURLException mue) {
                        FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request");
-                       log.error("Unexpected FE request processing error :", mue);
+                       log.error(EcompLoggerErrorCode.DATA_ERROR, "FeProxyServlet rewriteTarget", "sdc-FE", "Malformed URL Exception: ", mue);
                }
                catch (Exception e) {
-                       FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request");
-                       log.error("Unexpected FE request logging error :", e);
+            log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet rewriteTarget", "sdc-FE", "Unexpected FE request processing error: ", e);
+               }
+               if (log.isDebugEnabled()) {
+                       log.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl);
                }
-
-               log.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl);
 
                return redirectedUrl;
        }
@@ -85,53 +101,19 @@ public class FeProxyServlet extends SSLProxyServlet {
                        logFeResponse(request, response);
                } catch (Exception e) {
                        FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response");
-                       log.error("Unexpected FE response logging error :", e);
+            log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet onProxyResponseSuccess", "sdc-FE", "Unexpected FE response logging error: ", e);
                }
                super.onProxyResponseSuccess(request, proxyResponse, response);
        }
 
-       private void logFeRequest(HttpServletRequest httpRequest) {
-
-               MDC.clear();
-
-               Long transactionStartTime = System.currentTimeMillis();
-               // UUID - In FE, we are supposed to get the below header from UI.
-               // We do not generate it if it's missing - BE does.
-               String uuid = httpRequest.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
-               String serviceInstanceID = httpRequest.getHeader(Constants.X_ECOMP_SERVICE_ID_HEADER);
-
-               if (uuid != null && uuid.length() > 0) {
-                       // UserId for logging
-                       String userId = httpRequest.getHeader(Constants.USER_ID_HEADER);
-
-                       String remoteAddr = httpRequest.getRemoteAddr();
-                       String localAddr = httpRequest.getLocalAddr();
-
-                       mdcDataCache.put(uuid, new MdcData(serviceInstanceID, userId, remoteAddr, localAddr, transactionStartTime));
-
-                       updateMdc(uuid, serviceInstanceID, userId, remoteAddr, localAddr, null);
-               }
+       private void logFeRequest(HttpServletRequest httpRequest){
+               LogHandler.logFeRequest(httpRequest);
                inHttpRequest(httpRequest);
        }
 
-       private void logFeResponse(HttpServletRequest request, Response proxyResponse) {
-               String uuid = request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
-               String transactionRoundTime = null;
-
-               if (uuid != null) {
-                       MdcData mdcData = mdcDataCache.getIfPresent(uuid);
-                       if (mdcData != null) {
-                               Long transactionStartTime = mdcData.getTransactionStartTime();
-                               if (transactionStartTime != null) {// should'n ever be null, but
-                                       // just to be defensive
-                                       transactionRoundTime = Long.toString(System.currentTimeMillis() - transactionStartTime);
-                               }
-                               updateMdc(uuid, mdcData.getServiceInstanceID(), mdcData.getUserId(), mdcData.getRemoteAddr(), mdcData.getLocalAddr(), transactionRoundTime);
-                       }
-               }
+       private void logFeResponse(HttpServletRequest request, Response proxyResponse){
+               LogHandler.logFeResponse(request);
                outHttpResponse(proxyResponse);
-
-               MDC.clear();
        }
 
        // Extracted for purpose of clear method name, for logback %M parameter
@@ -144,27 +126,15 @@ public class FeProxyServlet extends SSLProxyServlet {
                log.info("SC=\"{}\"", proxyResponse.getStatus());
        }
 
-       private void updateMdc(String uuid, String serviceInstanceID, String userId, String remoteAddr, String localAddr, String transactionStartTime) {
-               MDC.put("uuid", uuid);
-               MDC.put("serviceInstanceID", serviceInstanceID);
-               MDC.put("userId", userId);
-               MDC.put("remoteAddr", remoteAddr);
-               MDC.put("localAddr", localAddr);
-               MDC.put("timer", transactionStartTime);
-       }
-
-       
-       
-       private String getModifiedUrl(HttpServletRequest request) throws MalformedURLException {
-               Configuration config = getConfiguration(request);
+       private String getModifiedUrl(Configuration config, PluginsConfiguration pluginConf, String uri, String queryString) throws MalformedURLException{
                if (config == null) {
-                       log.error("failed to retrive configuration.");
+            log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet getModifiedUrl", "sdc-FE", "failed to retrieve configuration.");
                        throw new RuntimeException("failed to read FE configuration");
                }
-               String uri = request.getRequestURI();
                String protocol;
                String host;
                String port;
+               String path = "";
                if (uri.contains(ONBOARDING_CONTEXT)){
                        uri = uri.replace(SDC1_FE_PROXY+ONBOARDING_CONTEXT,ONBOARDING_CONTEXT);
                        protocol = config.getOnboarding().getProtocolBe();
@@ -182,15 +152,16 @@ public class FeProxyServlet extends SSLProxyServlet {
                }
                else if (uri.contains(WORKFLOW_CONTEXT)){
                        uri = uri.replace(SDC1_FE_PROXY +WORKFLOW_CONTEXT,WORKFLOW_CONTEXT);
-                       String workflowPluginURL = getPluginConfiguration(request).getPluginsList()
+                       String workflowPluginURL = pluginConf.getPluginsList()
                                        .stream()
                                        .filter(plugin -> plugin.getPluginId().equalsIgnoreCase(PLUGIN_ID_WORKFLOW))
-                                       .map(Plugin::getPluginSourceUrl)
+                                       .map(Plugin::getPluginDiscoveryUrl)
                                        .findFirst().orElse(null);
 
                        java.net.URL workflowURL = new URL(workflowPluginURL);
                        protocol = workflowURL.getProtocol();
                        host = workflowURL.getHost();
+                       path = workflowURL.getPath();
                        port = String.valueOf(workflowURL.getPort());
                }
                else{
@@ -204,40 +175,143 @@ public class FeProxyServlet extends SSLProxyServlet {
                        }
                }       
 
-               String authority = getAuthority(host, port);
-               String queryString = getQueryString(request);
-               return  String.format(URL,protocol,authority,uri,queryString);
-
+               final String authority = getAuthority(host, port);
+               String modifiedUrl = String.format(URL, protocol, authority, path, uri);
+               if (StringUtils.isNotEmpty(queryString)) {
+                       modifiedUrl += "?" + queryString;
+               }
+                
+               return modifiedUrl;
        }
 
-       private PluginsConfiguration getPluginConfiguration(HttpServletRequest request) {
+       @VisibleForTesting
+       String redirectMsRequestToMservice(HttpServletRequest request, Configuration config) throws MalformedURLException {
+
+               boolean isMsToggledOn = isMsToggleOn(config);
+               String redirectValue;
+               if (isMsToggledOn) {
+                       redirectValue = handleMsToggleOnRedirect(request, config);
+               } else {
+                       redirectValue = handleMsToggleOffRedirect(request, config);
+               }
+               return redirectValue;
+       }
+private PluginsConfiguration getPluginConfiguration(HttpServletRequest request) {
                return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getPluginsConfiguration();
   }
+       private boolean isMsToggleOn(Configuration config) {
+               boolean toggleOn = true;
+               final CatalogFacadeMsConfig catalogFacadeMs = config.getCatalogFacadeMs();
+               if (catalogFacadeMs == null) {
+                       toggleOn = false;
+                       ;
+               } else if (isEmpty(catalogFacadeMs.getHealthCheckUri())) {
+                       toggleOn = false;
+               } else if (isEmpty(catalogFacadeMs.getHost())) {
+                       toggleOn = false;
+               } else if (isEmpty(catalogFacadeMs.getPath())) {
+                       toggleOn = false;
+               } else if (isEmpty(catalogFacadeMs.getProtocol())) {
+                       toggleOn = false;
+               } else if (catalogFacadeMs.getPort() == null) {
+                       toggleOn = false;
+               }
+               return toggleOn;
+       }
+       private String handleMsToggleOffRedirect(HttpServletRequest request, Configuration config) throws MalformedURLException {
+               String redirectValue;
+               String currentURI = request.getRequestURI();
+               if (isEmpty(request.getQueryString())) {
+                       // Catalog
+                       if (currentURI.endsWith(CATALOG_REQUEST_IDENTIFIER)) {
+                               String facadeSuffix = String.format("%s%s", FACADE_PATH_IDENTIFIER, CATALOG_REQUEST_IDENTIFIER);
+                               String nonFacadeUrl = currentURI.replace(facadeSuffix, "rest/v1/screen");
+                               redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, "excludeTypes=VFCMT&excludeTypes=Configuration");
+                       }
+                       // Home
+                       else if (currentURI.endsWith(HOME_REQUEST_IDENTIFIER)){
+                               redirectValue = getModifiedUrl(config, getPluginConfiguration(request), currentURI, getQueryString(request));
+                       }
+                       // Archive
+                       else if (currentURI.endsWith(ARCHIVE_PATH_IDENTIFIER)) {
+                               redirectValue = getModifiedUrl(config, getPluginConfiguration(request), currentURI, getQueryString(request));
+                       } else {
+                               String message = String.format("facade is toggled off, Could not rediret url %s", currentURI);
+                               log.error(message);
+                               throw new NotImplementedException(message);
+                       }
+               } else {
+                       // Left Pallet
+                       if (currentURI.contains("/latestversion/notabstract/metadata")) {
+                               String nonFacadeUrl = currentURI.replace(FACADE_PATH_IDENTIFIER, "rest");
+                               redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, getQueryString(request));
+                       }
+                       // Catalog with Query Params
+                       else if (currentURI.endsWith(CATALOG_REQUEST_IDENTIFIER)) {
+                               String facadeSuffix = String.format("%s%s", FACADE_PATH_IDENTIFIER, CATALOG_REQUEST_IDENTIFIER);
+                               String nonFacadeUrl = currentURI.replace(facadeSuffix, "rest/v1/screen");
+                               redirectValue = getModifiedUrl(config, getPluginConfiguration(request), nonFacadeUrl, "excludeTypes=VFCMT&excludeTypes=Configuration");
+                       } else {
+                               String message = String.format("facade is toggled off, Could not rediret url %s with query params %s",
+                                               currentURI, getQueryString(request));
+                               log.error(message);
+                               throw new NotImplementedException(message);
+                       }
+               }
+
+               return redirectValue;
+       }
 
+  private String handleMsToggleOnRedirect(HttpServletRequest request, Configuration config) {
+               String currentUrl = request.getRequestURL()
+                               .toString();
+               if (StringUtils.isEmpty(msUrl)) {
+                       // do that only once
+                       msUrl = String.format(MS_URL, config.getCatalogFacadeMs()
+                                       .getProtocol(),
+                                       config.getCatalogFacadeMs().getHost(),
+                                       config.getCatalogFacadeMs().getPort());
+               }
+               StringBuilder url;
+               String queryString;
+               String msPath = config.getCatalogFacadeMs().getPath();
+               if (currentUrl.endsWith(ARCHIVE_PATH_IDENTIFIER)) {
+                       url = new StringBuilder(msUrl + msPath + CATALOG_REQUEST_IDENTIFIER);
+                       queryString = "arc=true";
+               } else {
+                       url = new StringBuilder(msUrl + currentUrl.substring(currentUrl.indexOf(msPath)));
+                       queryString = request.getQueryString();
+               }
+               if (queryString != null) {
+                       url.append("?").append(queryString);
+               }
+               if (log.isDebugEnabled()) {
+                       log.debug("Redirect catalog request to {}", url.toString());
+               }
+               return url.toString();
+       }
 
+       @VisibleForTesting
+       boolean isMsRequest(String currentUrl) {
+               return currentUrl.contains(FACADE_PATH_IDENTIFIER) || currentUrl.endsWith(ARCHIVE_PATH_IDENTIFIER);
+       }
        private Configuration getConfiguration(HttpServletRequest request) {
                return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getConfiguration();
        }
 
        private String getAuthority(String host, String port) {
                String authority;
-               if (port==null){
-                       authority=host;
-               }
-               else{
-                       authority=host+":"+port;
+               if (port == null) {
+                       authority = host;
+               } else {
+                       authority = host + ":" + port;
                }
                return authority;
        }
-
-       private String getQueryString(HttpServletRequest request) {
-               String queryString = request.getQueryString();
-               if (queryString != null) {
-                       queryString="?"+queryString;
-               }
-               else{
-                       queryString="";
-               }
-               return queryString;
+       
+       private String getQueryString(HttpServletRequest request){
+               final String queryString = request.getQueryString();
+               return StringUtils.isEmpty(queryString) ? StringUtils.EMPTY : queryString;
        }
+
 }