diff options
Diffstat (limited to 'catalog-fe/src/main/java')
17 files changed, 1136 insertions, 815 deletions
diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/GzipFilter.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/filters/GzipFilter.java index f45bf82b3a..bb2207c422 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/GzipFilter.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/filters/GzipFilter.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * SDC * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.sdc.fe; +package org.openecomp.sdc.fe.filters; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -36,7 +36,7 @@ public class GzipFilter implements Filter { throws IOException, ServletException { - + final HttpServletResponse httpResponse = (HttpServletResponse) response; @@ -45,15 +45,15 @@ public class GzipFilter implements Filter { chain.doFilter(request, response); } - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } -} + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } +}
\ No newline at end of file diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/filters/SecurityFilter.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/filters/SecurityFilter.java new file mode 100644 index 0000000000..c615e4a44d --- /dev/null +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/filters/SecurityFilter.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.fe.filters; + + +import org.apache.commons.lang3.StringUtils; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; +import org.openecomp.sdc.common.log.wrappers.Logger; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.NoSuchElementException; + +public class SecurityFilter implements Filter { + private static final Logger log = Logger.getLogger(SecurityFilter.class.getName()); + + private static final String PORTAL_COOKIE_NAME_IS_NOT_SET = "Portal cookie name is not set in portal.properties file"; + + private List<String> excludedUrls; + + static final String PORTAL_COOKIE_NAME_KEY = "portal_cookie_name"; + static final String PORTAL_REDIRECT_URL_KEY = "ecomp_redirect_url"; + static final String FILTER_EXLUDED_URLS_KEY ="excludedUrls"; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + excludedUrls = Arrays.asList(filterConfig.getInitParameter(FILTER_EXLUDED_URLS_KEY).split(",")); + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + + final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + final HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; + + log.debug("SecurityFilter received request with URL {}", httpRequest.getRequestURL()); + //add redirecting to Portal if cookie is not provided + if (!excludedUrls.contains(httpRequest.getServletPath()) && !isRequestFromPortal(httpRequest.getCookies())) { + //redirect to portal app + log.debug("Request {} is not from Portal, redirecting there", httpRequest.getServletPath()); + httpResponse.sendRedirect(PortalApiProperties.getProperty(PORTAL_REDIRECT_URL_KEY)); + } + else { + filterChain.doFilter(servletRequest, servletResponse); + } + } + + @Override + public void destroy() { + + } + + private boolean isRequestFromPortal(Cookie[] cookies) { + String portalCookieValue = PortalApiProperties.getProperty(PORTAL_COOKIE_NAME_KEY); + if (StringUtils.isEmpty(portalCookieValue)) { + log.error(PORTAL_COOKIE_NAME_IS_NOT_SET); + throw new NoSuchElementException(PORTAL_COOKIE_NAME_IS_NOT_SET); + } + return cookies != null && Arrays.stream(cookies) + .anyMatch(c->StringUtils.equals(c.getName(), portalCookieValue)); + } +} diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTask.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTask.java new file mode 100644 index 0000000000..61d7597e37 --- /dev/null +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTask.java @@ -0,0 +1,437 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.fe.impl; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckWrapper; +import org.openecomp.sdc.common.config.EcompErrorEnum; +import org.openecomp.sdc.common.http.client.api.HttpRequest; +import org.openecomp.sdc.common.http.client.api.HttpResponse; +import org.openecomp.sdc.common.http.config.HttpClientConfig; +import org.openecomp.sdc.common.http.config.Timeouts; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.log.elements.ErrorLogOptionalData; +import org.openecomp.sdc.common.log.elements.LogFieldsMdcHandler; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.common.util.HealthCheckUtil; +import org.openecomp.sdc.fe.config.Configuration; +import org.openecomp.sdc.fe.config.FeEcompErrorManager; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_CATALOG_FACADE_MS; +import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_DCAE; +import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_ON_BOARDING; + +public class HealthCheckScheduledTask implements Runnable { + private static final Logger healthLogger = Logger.getLogger("asdc.fe.healthcheck"); + private static final Logger log = Logger.getLogger(HealthCheckScheduledTask.class.getName()); + private static final String LOG_PARTNER_NAME = "SDC.FE"; + private static final String LOG_TARGET_ENTITY_BE = "SDC.BE"; + private static final String LOG_TARGET_ENTITY_CONFIG = "SDC.FE.Configuration"; + private static final String LOG_TARGET_SERVICE_NAME_OB = "getOnboardingConfig"; + private static final String LOG_TARGET_SERVICE_NAME_DCAE = "getDCAEConfig"; + private static final String LOG_TARGET_SERVICE_NAME_FACADE = "getCatalogFacadeConfig"; + private static final String LOG_SERVICE_NAME = "/rest/healthCheck"; + private static LogFieldsMdcHandler mdcFieldsHandler = new LogFieldsMdcHandler(); + + private static final String URL = "%s://%s:%s/sdc2/rest/healthCheck"; + + private final List<String> healthCheckFeComponents = + Arrays.asList(HC_COMPONENT_ON_BOARDING, HC_COMPONENT_DCAE, HC_COMPONENT_CATALOG_FACADE_MS); + private static final HealthCheckUtil healthCheckUtil = new HealthCheckUtil(); + private static final String DEBUG_CONTEXT = "HEALTH_FE"; + private static final String EXTERNAL_HC_URL = "%s://%s:%s%s"; + private static String ONBOARDING_HC_URL; + private static String DCAE_HC_URL; + private static String CATALOG_FACADE_MS_HC_URL; + + private final HealthCheckService service; + + HealthCheckScheduledTask(HealthCheckService service) { + this.service = service; + } + + static String getOnboardingHcUrl() { + return ONBOARDING_HC_URL; + } + + static String getDcaeHcUrl() { + return DCAE_HC_URL; + } + + static String getCatalogFacadeMsHcUrl() { + return CATALOG_FACADE_MS_HC_URL; + } + + + @Override + public void run() { + mdcFieldsHandler.addInfoForErrorAndDebugLogging(LOG_PARTNER_NAME); + healthLogger.trace("Executing FE Health Check Task - Start"); + HealthCheckService.HealthStatus currentHealth = checkHealth(); + int currentHealthStatus = currentHealth.getStatusCode(); + healthLogger.trace("Executing FE Health Check Task - Status = {}", currentHealthStatus); + + // In case health status was changed, issue alarm/recovery + if (currentHealthStatus != service.getLastHealthStatus().getStatusCode()) { + log.trace("FE Health State Changed to {}. Issuing alarm / recovery alarm...", currentHealthStatus); + logFeAlarm(currentHealthStatus); + } + // Anyway, update latest response + service.setLastHealthStatus(currentHealth); + } + + private List<HealthCheckInfo> addHostedComponentsFeHealthCheck(String baseComponent, boolean requestedByBE) { + String healthCheckUrl = getExternalComponentHcUrl(baseComponent); + String serviceName = getExternalComponentHcUri(baseComponent); + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(baseComponent) + .targetServiceName(serviceName).build(); + + StringBuilder description = new StringBuilder(""); + int connectTimeoutMs = 3000; + int readTimeoutMs = service.getConfig().getHealthCheckSocketTimeoutInMs(5000); + + if (healthCheckUrl != null) { + ObjectMapper mapper = new ObjectMapper(); + try { + HttpResponse<String> response = HttpRequest.get(healthCheckUrl, new HttpClientConfig(new Timeouts(connectTimeoutMs, readTimeoutMs))); + int beStatus = response.getStatusCode(); + if (beStatus == HttpStatus.SC_OK || beStatus == HttpStatus.SC_INTERNAL_SERVER_ERROR) { + String beJsonResponse = response.getResponse(); + return convertResponse(beJsonResponse, mapper, baseComponent, description, beStatus); + } else { + description.append("Response code: " + beStatus); + log.trace("{} Health Check Response code: {}", baseComponent, beStatus); + } + } catch (Exception e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, serviceName, errorLogOptionalData, baseComponent + " unexpected response ", e); + description.append(baseComponent + " Unexpected response: " + e.getMessage()); + } + } else { + description.append(baseComponent + " health check Configuration is missing"); + } + + String compName = requestedByBE ? Constants.HC_COMPONENT_FE : baseComponent; + return Collections.singletonList(new HealthCheckInfo( + compName, + HealthCheckInfo.HealthCheckStatus.DOWN, + null, + description.toString())); + } + + private String getExternalComponentHcUri(String baseComponent) { + String healthCheckUri = null; + switch (baseComponent) { + case HC_COMPONENT_ON_BOARDING: + healthCheckUri = service.getConfig().getOnboarding().getHealthCheckUriFe(); + break; + case HC_COMPONENT_DCAE: + healthCheckUri = service.getConfig().getDcae().getHealthCheckUri(); + break; + case HC_COMPONENT_CATALOG_FACADE_MS: + healthCheckUri = service.getConfig().getCatalogFacadeMs().getHealthCheckUri(); + break; + default: + log.debug("Unsupported base component {}", baseComponent); + break; + } + return healthCheckUri; + } + + + @VisibleForTesting + String getExternalComponentHcUrl(String baseComponent) { + String healthCheckUrl = null; + switch (baseComponent) { + case HC_COMPONENT_ON_BOARDING: + healthCheckUrl = getOnboardingHealthCheckUrl(); + break; + case HC_COMPONENT_DCAE: + healthCheckUrl = getDcaeHealthCheckUrl(); + break; + case HC_COMPONENT_CATALOG_FACADE_MS: + healthCheckUrl = getCatalogFacadeHealthCheckUrl(); + break; + default: + log.debug("Unsupported base component {}", baseComponent); + break; + } + return healthCheckUrl; + } + + private void logFeAlarm(int lastFeStatus) { + switch (lastFeStatus) { + case 200: + FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT, EcompErrorEnum.FeHealthCheckRecovery, "FE Health Recovered"); + FeEcompErrorManager.getInstance().logFeHealthCheckRecovery("FE Health Recovered"); + break; + case 500: + FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT, EcompErrorEnum.FeHealthCheckError, "Connection with ASDC-BE is probably down"); + FeEcompErrorManager.getInstance().logFeHealthCheckError("Connection with ASDC-BE is probably down"); + break; + default: + break; + } + } + + private HealthCheckService.HealthStatus checkHealth() { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + Configuration config = service.getConfig(); + + HealthCheckWrapper feAggHealthCheck; + boolean aggregateFeStatus = false; + String redirectedUrl = String.format(URL, config.getBeProtocol(), config.getBeHost(), + Constants.HTTPS.equals(config.getBeProtocol()) ? config.getBeSslPort() : config.getBeHttpPort()); + int connectTimeoutMs = 3000; + int readTimeoutMs = config.getHealthCheckSocketTimeoutInMs(5000); + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(LOG_TARGET_ENTITY_BE) + .targetServiceName(LOG_SERVICE_NAME).build(); + + try { + HttpResponse<String> response = HttpRequest.get(redirectedUrl, new HttpClientConfig(new Timeouts(connectTimeoutMs, readTimeoutMs))); + log.debug("HC call to BE - status code is {}", response.getStatusCode()); + String beJsonResponse = response.getResponse(); + feAggHealthCheck = getFeHealthCheckInfos(gson, beJsonResponse); + if (response.getStatusCode() != HttpStatus.SC_INTERNAL_SERVER_ERROR) { + aggregateFeStatus = healthCheckUtil.getAggregateStatus(feAggHealthCheck.getComponentsInfo(), getExcludedComponentList()); + } + //Getting aggregate FE status + return new HealthCheckService.HealthStatus(aggregateFeStatus ? HttpStatus.SC_OK : HttpStatus.SC_INTERNAL_SERVER_ERROR, gson.toJson(feAggHealthCheck)); + + } + catch (Exception e) { + log.debug("Health Check error when trying to connect to BE or external FE. Error: {}", e); + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LOG_SERVICE_NAME, errorLogOptionalData, + "Health Check error when trying to connect to BE or external FE.", e.getMessage()); + FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT,EcompErrorEnum.FeHealthCheckGeneralError, "Unexpected FE Health check error"); + FeEcompErrorManager.getInstance().logFeHealthCheckGeneralError("Unexpected FE Health check error"); + return new HealthCheckService.HealthStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR, gson.toJson(getBeDownCheckInfos())); + } + } + + @VisibleForTesting + List<String> getExcludedComponentList() { + List <String> excludedComponentList = Lists.newArrayList(service.getConfig().getHealthStatusExclude()); + if (isCatalogFacadeMsExcluded()) { + if (log.isInfoEnabled()) { + log.info(HC_COMPONENT_CATALOG_FACADE_MS + " has been added to the Healthcheck exclude list"); + } + excludedComponentList.add(HC_COMPONENT_CATALOG_FACADE_MS); + } + return excludedComponentList; + } + + private boolean isCatalogFacadeMsExcluded() { + //CATALOG_FACADE_MS is excluded if it is not configured + return service.getConfig().getCatalogFacadeMs() == null || StringUtils.isEmpty(service.getConfig().getCatalogFacadeMs().getPath()); + } + + private HealthCheckWrapper getFeHealthCheckInfos(Gson gson, String responseString) { + Type wrapperType = new TypeToken<HealthCheckWrapper>() { + }.getType(); + HealthCheckWrapper healthCheckWrapper = gson.fromJson(responseString, wrapperType); + String description = "OK"; + healthCheckWrapper.getComponentsInfo() + .add(new HealthCheckInfo(Constants.HC_COMPONENT_FE, HealthCheckInfo.HealthCheckStatus.UP, ExternalConfiguration.getAppVersion(), description)); + + //add FE hosted components + for (String component : healthCheckFeComponents) { + buildHealthCheckListForComponent(component, healthCheckWrapper); + } + return healthCheckWrapper; + } + + private void buildHealthCheckListForComponent(String component, HealthCheckWrapper healthCheckWrapper) { + + HealthCheckInfo componentHCInfoFromBE = getComponentHcFromList(component, healthCheckWrapper.getComponentsInfo()); + List<HealthCheckInfo> componentHCInfoList = addHostedComponentsFeHealthCheck(component, componentHCInfoFromBE != null); + HealthCheckInfo calculateStatusFor; + if (componentHCInfoFromBE != null) { + if (log.isDebugEnabled()) { + log.debug("{} component healthcheck info has been received from the BE and from the component itself", component); + } + //update the subcomponents's HC if exist and recalculate the component status according to the subcomponets HC + calculateStatusFor = updateSubComponentsInfoOfBeHc(componentHCInfoFromBE, componentHCInfoList); + } + else { + + //this component is not in the BE HC response, need to add it and calculate the aggregated status + if (log.isDebugEnabled()) { + log.debug("{} component healthcheck info has been received from the component itself, it is not monitored by the BE", component); + } + //we assume that response from components which HC is not requested by BE have only one entry in the responded list + calculateStatusFor = componentHCInfoList.get(0); + healthCheckWrapper.getComponentsInfo() + .add(calculateStatusFor); + + } + calculateAggregatedStatus(calculateStatusFor); + + } + + @VisibleForTesting + HealthCheckInfo updateSubComponentsInfoOfBeHc(HealthCheckInfo componentHCInfoFromBE, List<HealthCheckInfo> componentHcReceivedByFE) { + if (!CollectionUtils.isEmpty(componentHcReceivedByFE)) { + //this component HC is received from BE, just need to calculate the status for that + if (componentHCInfoFromBE.getComponentsInfo() == null) { + componentHCInfoFromBE.setComponentsInfo(new ArrayList<>()); + } + componentHCInfoFromBE.getComponentsInfo().addAll(componentHcReceivedByFE); + } + return componentHCInfoFromBE; + } + + private HealthCheckInfo getComponentHcFromList(String component, List<HealthCheckInfo> hcList) { + return hcList.stream().filter(c -> c.getHealthCheckComponent().equals(component)).findFirst().orElse(null); + } + + private void calculateAggregatedStatus(HealthCheckInfo baseComponentHCInfo) { + if (!CollectionUtils.isEmpty(baseComponentHCInfo.getComponentsInfo())) { + boolean status = healthCheckUtil.getAggregateStatus(baseComponentHCInfo.getComponentsInfo(), getExcludedComponentList()); + baseComponentHCInfo.setHealthCheckStatus(status ? + HealthCheckInfo.HealthCheckStatus.UP : HealthCheckInfo.HealthCheckStatus.DOWN); + + String componentsDesc = healthCheckUtil.getAggregateDescription(baseComponentHCInfo.getComponentsInfo()); + if (!StringUtils.isEmpty(componentsDesc)) { //aggregated description contains all the internal components desc + baseComponentHCInfo.setDescription(componentsDesc); + } + } + } + + private HealthCheckWrapper getBeDownCheckInfos() { + List<HealthCheckInfo> healthCheckInfos = new ArrayList<>(); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_FE, HealthCheckInfo.HealthCheckStatus.UP, + ExternalConfiguration.getAppVersion(), "OK")); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_BE, HealthCheckInfo.HealthCheckStatus.DOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_JANUSGRAPH, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_CASSANDRA, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_ON_BOARDING, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(Constants.HC_COMPONENT_DCAE, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_CATALOG_FACADE_MS, HealthCheckInfo.HealthCheckStatus.UNKNOWN, null, null)); + return new HealthCheckWrapper(healthCheckInfos, "UNKNOWN", "UNKNOWN"); + } + + String buildHealthCheckUrl(String protocol, String host, Integer port, String uri) { + return String.format(EXTERNAL_HC_URL, protocol, host, port, uri); + } + + private String getOnboardingHealthCheckUrl() { + Configuration.OnboardingConfig onboardingConfig = service.getConfig().getOnboarding(); + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(LOG_TARGET_ENTITY_CONFIG) + .targetServiceName(LOG_TARGET_SERVICE_NAME_OB).build(); + + if (StringUtils.isEmpty(ONBOARDING_HC_URL)) { + if (onboardingConfig != null) { + ONBOARDING_HC_URL = buildHealthCheckUrl( + onboardingConfig.getProtocolFe(), onboardingConfig.getHostFe(), + onboardingConfig.getPortFe(), onboardingConfig.getHealthCheckUriFe()); + } + else { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LOG_SERVICE_NAME, errorLogOptionalData, + "Onboarding health check configuration is missing."); + } + } + return ONBOARDING_HC_URL; + } + + private String getDcaeHealthCheckUrl() { + Configuration.DcaeConfig dcaeConfig = service.getConfig().getDcae(); + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(LOG_TARGET_ENTITY_CONFIG) + .targetServiceName(LOG_TARGET_SERVICE_NAME_DCAE).build(); + + if (StringUtils.isEmpty(DCAE_HC_URL)) { + if (dcaeConfig != null) { + DCAE_HC_URL = buildHealthCheckUrl( + dcaeConfig.getProtocol(), dcaeConfig.getHost(), + dcaeConfig.getPort(), dcaeConfig.getHealthCheckUri()); + } + else { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LOG_SERVICE_NAME, errorLogOptionalData, + "DCAE health check configuration is missing."); + } + } + return DCAE_HC_URL; + } + + private String getCatalogFacadeHealthCheckUrl() { + Configuration.CatalogFacadeMsConfig catalogFacadeMsConfig = service.getConfig().getCatalogFacadeMs(); + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(LOG_TARGET_ENTITY_CONFIG) + .targetServiceName(LOG_TARGET_SERVICE_NAME_FACADE).build(); + + if (StringUtils.isEmpty(CATALOG_FACADE_MS_HC_URL)) { + if (catalogFacadeMsConfig != null) { + CATALOG_FACADE_MS_HC_URL = buildHealthCheckUrl( + catalogFacadeMsConfig.getProtocol(), catalogFacadeMsConfig.getHost(), + catalogFacadeMsConfig.getPort(), catalogFacadeMsConfig.getHealthCheckUri()); + } + else { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LOG_SERVICE_NAME, errorLogOptionalData, + "Catalog Facade MS health check configuration is missing."); + } + } + return CATALOG_FACADE_MS_HC_URL; + } + + + private List<HealthCheckInfo> convertResponse(String beJsonResponse, ObjectMapper mapper, String baseComponent, StringBuilder description, int beStatus) { + ErrorLogOptionalData errorLogOptionalData = ErrorLogOptionalData.newBuilder().targetEntity(baseComponent) + .targetServiceName(LOG_SERVICE_NAME).build(); + + try { + Map<String, Object> healthCheckMap = mapper.readValue(beJsonResponse, new TypeReference<Map<String, Object>>() { + }); + if (healthCheckMap.containsKey("componentsInfo")) { + return mapper.convertValue(healthCheckMap.get("componentsInfo"), new TypeReference<List<HealthCheckInfo>>() { + }); + } else { + description.append("Internal components are missing"); + } + } catch (JsonSyntaxException | IOException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LOG_SERVICE_NAME, errorLogOptionalData, + baseComponent + " Unexpected response body ", e); + description.append(baseComponent) + .append("Unexpected response body. Response code: ") + .append(beStatus); + } + return new ArrayList<>(); + } +}
\ No newline at end of file diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckService.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckService.java new file mode 100644 index 0000000000..d5cfaeca7e --- /dev/null +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HealthCheckService.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.fe.impl; + +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.fe.config.Configuration; +import org.openecomp.sdc.fe.config.ConfigurationManager; + +import javax.servlet.ServletContext; +import javax.ws.rs.core.Response; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + + +public class HealthCheckService { + + private static final Logger healthLogger = Logger.getLogger("asdc.fe.healthcheck"); + /** + * This executor will execute the health check task. + */ + private ScheduledExecutorService healthCheckExecutor = + Executors.newSingleThreadScheduledExecutor((Runnable r) -> new Thread(r, "FE-Health-Check-Thread")); + + private final HealthCheckScheduledTask task ; + + + public HealthCheckService(ServletContext context) { + this.context = context; + this.task = new HealthCheckScheduledTask(this); + } + + public Configuration getConfig(){ + return ((ConfigurationManager) context.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)) + .getConfiguration(); + } + + void setLastHealthStatus(HealthStatus lastHealthStatus) { + this.lastHealthStatus = lastHealthStatus; + } + + private HealthStatus lastHealthStatus = new HealthStatus(500, "{}"); + private ServletContext context; + + public void start(int interval) { + this.healthCheckExecutor.scheduleAtFixedRate( getTask() , 0, interval, TimeUnit.SECONDS); + } + + /** + * To be used by the HealthCheckServlet + * + * @return + */ + public Response getFeHealth() { + return this.buildResponse(lastHealthStatus); + } + + private Response buildResponse(HealthStatus healthStatus) { + healthLogger.trace("FE and BE health check status: {}", healthStatus.getBody()); + return Response.status(healthStatus.getStatusCode()).entity(healthStatus.getBody()).build(); + } + + public HealthStatus getLastHealthStatus() { + return lastHealthStatus; + } + public HealthCheckScheduledTask getTask() { + return task; + } + + //immutable + static class HealthStatus { + + public void setBody(String body) { + this.body = body; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + private String body; + private int statusCode; + + public HealthStatus(int code, String body) { + this.body = body; + this.statusCode = code; + } + + public int getStatusCode() { + return statusCode; + } + + public String getBody() { + return body; + } + } + + + +} diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HttpRequestInfo.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HttpRequestInfo.java index 05e61034ff..717c7265ad 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HttpRequestInfo.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HttpRequestInfo.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.fe.impl; import com.google.common.annotations.VisibleForTesting; + import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/LogHandler.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/LogHandler.java new file mode 100644 index 0000000000..b97379b399 --- /dev/null +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/LogHandler.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.fe.impl; + +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.api.ILogConfiguration; +import org.openecomp.sdc.common.log.elements.LogFieldsMdcHandler; +import org.slf4j.MDC; + +import javax.servlet.http.HttpServletRequest; + +public class LogHandler { + public static final String UUID = "uuid"; + public static final String TRANSACTION_START_TIME = "transactionStartTime"; + + public static void logFeRequest(HttpServletRequest httpRequest) { + Long transactionStartTime = System.currentTimeMillis(); + String uuid = LogFieldsMdcHandler.getInstance().getKeyRequestId(); + String serviceInstanceID = httpRequest.getHeader(Constants.X_ECOMP_SERVICE_ID_HEADER); + + if (uuid != null && uuid.length() > 0) { + String userId = httpRequest.getHeader(Constants.USER_ID_HEADER); + String remoteAddr = httpRequest.getRemoteAddr(); + String localAddr = httpRequest.getLocalAddr(); + + httpRequest.setAttribute(UUID,uuid); + httpRequest.setAttribute(TRANSACTION_START_TIME,transactionStartTime); + + updateMdc(uuid, serviceInstanceID, userId, remoteAddr, localAddr, null); + } + } + + public static void logFeResponse(HttpServletRequest request) { + String uuid = (String)request.getAttribute(UUID); + String serviceInstanceID = request.getHeader(Constants.X_ECOMP_SERVICE_ID_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String remoteAddr = request.getRemoteAddr(); + String localAddr = request.getLocalAddr(); + String transactionRoundTime = null; + + if (uuid != null) { + Long transactionStartTime = (Long)request.getAttribute(TRANSACTION_START_TIME); + if(transactionStartTime != null){ + transactionRoundTime = Long.toString(System.currentTimeMillis() - transactionStartTime); + } + updateMdc(uuid, serviceInstanceID, userId, remoteAddr, localAddr, transactionRoundTime); + } + } + + private static void updateMdc(String uuid, String serviceInstanceID, String userId, String remoteAddr, String localAddr, String transactionElapsedTime) { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, uuid); + MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, serviceInstanceID); + MDC.put("userId", userId); + MDC.put("remoteAddr", remoteAddr); + MDC.put("localAddr", localAddr); + MDC.put(ILogConfiguration.MDC_ELAPSED_TIME, transactionElapsedTime); + } +} diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java index 6461ccfad6..14b76d4679 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/PluginStatusBL.java @@ -28,18 +28,17 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpHead; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.InvalidArgumentException; import org.openecomp.sdc.fe.config.ConfigurationManager; import org.openecomp.sdc.fe.config.PluginsConfiguration; import org.openecomp.sdc.fe.config.PluginsConfiguration.Plugin; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; public class PluginStatusBL { - private static final Logger LOGGER = LoggerFactory.getLogger(PluginStatusBL.class.getName()); + private static final Logger log = Logger.getLogger(PluginStatusBL.class.getName()); private final Gson gson; private final CloseableHttpClient client; private final PluginsConfiguration pluginsConfiguration; @@ -60,14 +59,14 @@ public class PluginStatusBL { } public String getPluginsList() { - String result; + String result = null; if (pluginsConfiguration == null || pluginsConfiguration.getPluginsList() == null) { - LOGGER.warn("Configuration of type {} was not found", PluginsConfiguration.class); + log.warn("Configuration of type {} was not found", PluginsConfiguration.class); throw new InvalidArgumentException("the plugin configuration was not read successfully."); } else { - LOGGER.debug("The value returned from getConfig is {}", pluginsConfiguration); + log.debug("The value returned from getConfig is {}", pluginsConfiguration); result = gson.toJson(pluginsConfiguration.getPluginsList()); } @@ -78,11 +77,11 @@ public class PluginStatusBL { String result = null; if (pluginsConfiguration == null || pluginsConfiguration.getPluginsList() == null) { - LOGGER.warn("Configuration of type {} was not found", PluginsConfiguration.class); + log.warn("Configuration of type {} was not found", PluginsConfiguration.class); throw new InvalidArgumentException("the plugin configuration was not read successfully."); } else { - LOGGER.debug("The value returned from getConfig is {}", pluginsConfiguration); + log.debug("The value returned from getConfig is {}", pluginsConfiguration); Integer connectionTimeout = pluginsConfiguration.getConnectionTimeout(); this.requestConfig = RequestConfig.custom() .setSocketTimeout(connectionTimeout) @@ -104,17 +103,17 @@ public class PluginStatusBL { private boolean checkPluginAvailability(Plugin plugin) { boolean result = false; - LOGGER.debug("sending head request to id:{} url:{}", plugin.getPluginId(), plugin.getPluginDiscoveryUrl()); + log.debug("sending head request to id:{} url:{}", plugin.getPluginId(), plugin.getPluginDiscoveryUrl()); HttpHead head = new HttpHead(plugin.getPluginDiscoveryUrl()); head.setConfig(this.requestConfig); try (CloseableHttpResponse response = this.client.execute(head)) { result = response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK; - LOGGER.debug("The plugin {} is {} with result {}", plugin.getPluginId(), (result ? "online" : "offline"), result); + log.debug("The plugin {} is {} with result {}", plugin.getPluginId(), (result ? "online" : "offline"), result); } catch (IOException e) { - LOGGER.debug("The plugin {} is offline", plugin.getPluginId()); - LOGGER.debug("Exception:", e); + log.debug("The plugin {} is offline", plugin.getPluginId()); + log.debug("Exception:", e); } return result; diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/FEAppContextListener.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/FEAppContextListener.java index a672b1b201..70cb27e93b 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/FEAppContextListener.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/FEAppContextListener.java @@ -3,7 +3,6 @@ * SDC * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (c) 2019 Samsung * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,42 +20,25 @@ package org.openecomp.sdc.fe.listen; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.listener.AppContextListener; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.fe.config.ConfigurationManager; +import org.openecomp.sdc.fe.impl.HealthCheckService; import org.openecomp.sdc.fe.impl.PluginStatusBL; import org.openecomp.sdc.fe.monitoring.FeMonitoringService; -import org.openecomp.sdc.fe.servlets.HealthCheckService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class FEAppContextListener extends AppContextListener implements ServletContextListener { - private static final int HEALTH_CHECK_INTERVAL = 5; - private static final int PROBE_INTERVAL = 15; - private static Logger log = LoggerFactory.getLogger(FEAppContextListener.class.getName()); + private static Logger log = Logger.getLogger(FEAppContextListener.class.getName()); + private static final int HEALTH_CHECHK_INTERVALE = 5; + private static final int PROBE_INTERVALE = 15; public void contextInitialized(ServletContextEvent context) { @@ -68,22 +50,17 @@ public class FEAppContextListener extends AppContextListener implements ServletC ExternalConfiguration.getAppName()); context.getServletContext().setAttribute(Constants.CONFIGURATION_MANAGER_ATTR, configurationManager); - try { - PluginStatusBL pbl = new PluginStatusBL(buildRestClient()); - context.getServletContext().setAttribute(Constants.PLUGIN_BL_COMPONENT, pbl); - } catch (SSLException e) { - log.debug("ERROR: Build rest client failed because ", e); - return; - } + PluginStatusBL pbl = new PluginStatusBL(); + context.getServletContext().setAttribute(Constants.PLUGIN_BL_COMPONENT, pbl); // Health Check service HealthCheckService hcs = new HealthCheckService(context.getServletContext()); - hcs.start(configurationManager.getConfiguration().getHealthCheckIntervalInSeconds(HEALTH_CHECK_INTERVAL)); + hcs.start(configurationManager.getConfiguration().getHealthCheckIntervalInSeconds(HEALTH_CHECHK_INTERVALE)); context.getServletContext().setAttribute(Constants.HEALTH_CHECK_SERVICE_ATTR, hcs); // Monitoring service FeMonitoringService fms = new FeMonitoringService(context.getServletContext()); - fms.start(configurationManager.getConfiguration().getSystemMonitoring().getProbeIntervalInSeconds(PROBE_INTERVAL)); + fms.start(configurationManager.getConfiguration().getSystemMonitoring().getProbeIntervalInSeconds(PROBE_INTERVALE)); if (configurationManager.getConfiguration() == null) { log.debug("ERROR: configuration was not properly loaded"); @@ -109,21 +86,4 @@ public class FEAppContextListener extends AppContextListener implements ServletC } - private CloseableHttpClient buildRestClient() throws SSLException { - SSLContextBuilder builder = new SSLContextBuilder(); - try { - builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( - SSLContext.getDefault(), NoopHostnameVerifier.INSTANCE); - Registry<ConnectionSocketFactory> registry = - RegistryBuilder.<ConnectionSocketFactory>create() - .register("http", new PlainConnectionSocketFactory()).register("https", sslsf) - .build(); - PoolingHttpClientConnectionManager cm = - new PoolingHttpClientConnectionManager(registry); - return HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build(); - } catch (NoSuchAlgorithmException | KeyStoreException e) { - throw new SSLException(e); - } - } } diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigMgrServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigMgrServlet.java index 8608506694..c2ea7250d2 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigMgrServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigMgrServlet.java @@ -21,12 +21,11 @@ package org.openecomp.sdc.fe.servlets; import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.rest.api.RestConfigurationInfo; import org.openecomp.sdc.common.servlets.BasicServlet; import org.openecomp.sdc.fe.config.Configuration; import org.openecomp.sdc.fe.config.ConfigurationManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -43,7 +42,7 @@ import javax.ws.rs.core.MediaType; @Path("/configmgr") public class ConfigMgrServlet extends BasicServlet { - private static Logger log = LoggerFactory.getLogger(ConfigMgrServlet.class.getName()); + private static Logger log = Logger.getLogger(ConfigMgrServlet.class.getName()); @GET @Path("/get") diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigServlet.java index f3880ed791..f5d1736074 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigServlet.java @@ -21,12 +21,12 @@ package org.openecomp.sdc.fe.servlets; import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.fe.config.FeEcompErrorManager; -import org.openecomp.sdc.fe.impl.PluginStatusBL; +import org.openecomp.sdc.exception.NotFoundException; import org.openecomp.sdc.fe.config.ConfigurationManager; +import org.openecomp.sdc.fe.config.FeEcompErrorManager; import org.openecomp.sdc.fe.config.WorkspaceConfiguration; -import org.openecomp.sdc.exception.NotFoundException; - +import org.openecomp.sdc.fe.impl.PluginStatusBL; +import org.owasp.esapi.ESAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +47,7 @@ import javax.ws.rs.core.Response.Status; @Path("/config") public class ConfigServlet extends LoggingServlet { - private static final Logger LOGGER = LoggerFactory.getLogger(ConfigServlet.class.getName()); + private static final Logger log = LoggerFactory.getLogger(ConfigServlet.class.getName()); public static final String UNEXPECTED_FE_RESPONSE_LOGGING_ERROR = "Unexpected FE response logging error :"; public static final String ERROR_FE_RESPONSE = "FE Response"; @@ -68,7 +68,7 @@ public class ConfigServlet extends LoggingServlet { if (configuration == null) { throw new NotFoundException(WorkspaceConfiguration.class.getSimpleName()); } - LOGGER.info("The value returned from getConfig is {}", configuration); + log.info("The value returned from getConfig is {}", configuration); String result = gson.toJson(configuration); Response response = Response.status(Status.OK).entity(result).build(); logFeResponse(request, response); @@ -76,7 +76,7 @@ public class ConfigServlet extends LoggingServlet { return response; } catch (Exception e) { FeEcompErrorManager.getInstance().logFeHttpLoggingError(ERROR_FE_RESPONSE); - LOGGER.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); + log.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("{}").build(); } @@ -104,7 +104,7 @@ public class ConfigServlet extends LoggingServlet { return response; } catch (Exception e) { FeEcompErrorManager.getInstance().logFeHttpLoggingError( ERROR_FE_RESPONSE); - LOGGER.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); + log.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("{}").build(); } @@ -113,11 +113,11 @@ public class ConfigServlet extends LoggingServlet { @GET @Path("/ui/plugins/{pluginId}/online") @Produces(MediaType.APPLICATION_JSON) - public Response getPluginOnlineState(@PathParam("pluginId") final String pluginId, @Context final HttpServletRequest request) { + public Response getPluginOnlineState(@PathParam("pluginId") String pluginId, @Context final HttpServletRequest request) { try { logFeRequest(request); - + pluginId = ESAPI.encoder().encodeForHTML(pluginId); ServletContext context = request.getSession().getServletContext(); PluginStatusBL pluginStatusBL = (PluginStatusBL) context.getAttribute(Constants.PLUGIN_BL_COMPONENT); @@ -125,7 +125,7 @@ public class ConfigServlet extends LoggingServlet { String result = pluginStatusBL.getPluginAvailability(pluginId); if (result == null) { - LOGGER.debug("Plugin with pluginId: {} was not found in the configuration", pluginId); + log.debug("Plugin with pluginId: {} was not found in the configuration", pluginId); return Response.status(Status.NOT_FOUND).entity("Plugin with pluginId:\"" + pluginId + "\" was not found in the configuration").build(); } @@ -136,13 +136,13 @@ public class ConfigServlet extends LoggingServlet { return response; } catch (Exception e) { FeEcompErrorManager.getInstance().logFeHttpLoggingError(ERROR_FE_RESPONSE); - LOGGER.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); + log.error(UNEXPECTED_FE_RESPONSE_LOGGING_ERROR, e); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("{}").build(); } } protected void inHttpRequest(HttpServletRequest httpRequest) { - LOGGER.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol()); + log.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol()); } /** @@ -151,6 +151,6 @@ public class ConfigServlet extends LoggingServlet { * @param response http response */ protected void outHttpResponse(Response response) { - LOGGER.info("SC=\"{}\"", response.getStatus()); + log.info("SC=\"{}\"", response.getStatus()); } } diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServlet.java index fbf81b432e..5243366e85 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServlet.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.fe.servlets; import com.jcabi.aspects.Loggable; import org.openecomp.sdc.common.servlets.BasicServlet; +import org.openecomp.sdc.fe.impl.HealthCheckService; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeProxyServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeProxyServlet.java index 1c7b174c57..3ea660abbe 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeProxyServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeProxyServlet.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,218 +20,297 @@ package org.openecomp.sdc.fe.servlets; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; +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.MDC; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.MalformedURLException; import java.net.URL; -import java.util.concurrent.TimeUnit; + +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 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 LOGGER = Logger.getLogger(FeProxyServlet.class); - private static final int EXPIRE_DURATION = 10; - private static Cache<String, MdcData> mdcDataCache = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_DURATION, TimeUnit.SECONDS).build(); - - - @Override - protected String rewriteTarget(HttpServletRequest request) { - String originalUrl = ""; - String redirectedUrl = ""; - - try { - logFeRequest(request); - - originalUrl = request.getRequestURL().toString(); - redirectedUrl = getModifiedUrl(request); - - } catch (MalformedURLException mue) { - FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request"); - LOGGER.error(EcompLoggerErrorCode.DATA_ERROR, "FeProxyServlet rewriteTarget", "sdc-FE", "Malformed URL Exception: ", mue); - } catch (Exception e) { - FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Request"); - LOGGER.error(EcompLoggerErrorCode.UNKNOWN_ERROR, "FeProxyServlet rewriteTarget", "sdc-FE", "Unexpected FE request processing error: ", e); - } - - LOGGER.debug("FeProxyServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl); - - return redirectedUrl; - } - - @Override - protected void onProxyResponseSuccess(HttpServletRequest request, HttpServletResponse proxyResponse, Response response) { - try { - logFeResponse(request, response); - } catch (Exception e) { - FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response"); - LOGGER.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); - } - 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); - } - } - outHttpResponse(proxyResponse); - - MDC.clear(); - } - - // Extracted for purpose of clear method name, for logback %M parameter - private void inHttpRequest(HttpServletRequest httpRequest) { - LOGGER.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol()); - } - - // Extracted for purpose of clear method name, for logback %M parameter - private void outHttpResponse(Response proxyResponse) { - LOGGER.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); - if (config == null) { - LOGGER.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; - if (uri.contains(ONBOARDING_CONTEXT)) { - uri = uri.replace(SDC1_FE_PROXY + ONBOARDING_CONTEXT, ONBOARDING_CONTEXT); - protocol = config.getOnboarding().getProtocolBe(); - host = config.getOnboarding().getHostBe(); - port = config.getOnboarding().getPortBe().toString(); - } else if (uri.contains(DCAED_CONTEXT)) { - uri = uri.replace(SDC1_FE_PROXY + DCAED_CONTEXT, DCAED_CONTEXT); - protocol = config.getBeProtocol(); - host = config.getBeHost(); - if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) { - port = config.getBeHttpPort().toString(); - } else { - port = config.getBeSslPort().toString(); - } - } else if (uri.contains(WORKFLOW_CONTEXT)) { - String workflowPluginURL = getPluginConfiguration(request).getPluginsList() - .stream() - .filter(plugin -> plugin.getPluginId().equalsIgnoreCase(PLUGIN_ID_WORKFLOW)) - .map(Plugin::getPluginDiscoveryUrl) - .findFirst().orElse(null); - - java.net.URL workflowURL = new URL(workflowPluginURL); - protocol = workflowURL.getProtocol(); - host = workflowURL.getHost(); - port = String.valueOf(workflowURL.getPort()); - uri = uri.replace(SDC1_FE_PROXY + WORKFLOW_CONTEXT, workflowURL.getPath() + WORKFLOW_CONTEXT); - } else { - uri = uri.replace(SDC1_FE_PROXY, "/sdc2"); - protocol = config.getBeProtocol(); - host = config.getBeHost(); - if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) { - port = config.getBeHttpPort().toString(); - } else { - port = config.getBeSslPort().toString(); - } - } - - String authority = getAuthority(host, port); - String queryString = getQueryString(request); - return String.format(URL, protocol, authority, uri, queryString); - - } - - private PluginsConfiguration getPluginConfiguration(HttpServletRequest request) { - return ((ConfigurationManager) request.getSession().getServletContext().getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getPluginsConfiguration(); - } - - 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; - } - return authority; - } - - private String getQueryString(HttpServletRequest request) { - String queryString = request.getQueryString(); - if (queryString != null) { - queryString = "?" + queryString; - } else { - queryString = ""; - } - return queryString; - } + private static final long serialVersionUID = 1L; + private static final String URL = "%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"; + 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=""; + String redirectedUrl = ""; + + try { + logFeRequest(request); + originalUrl = request.getRequestURL().toString(); + + 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(EcompLoggerErrorCode.DATA_ERROR, "FeProxyServlet rewriteTarget", "sdc-FE", "Malformed URL Exception: ", mue); + } + catch (Exception 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); + } + + return redirectedUrl; + } + + @Override + protected void onProxyResponseSuccess(HttpServletRequest request, HttpServletResponse proxyResponse, Response response) { + try { + logFeResponse(request, response); + } catch (Exception e) { + FeEcompErrorManager.getInstance().logFeHttpLoggingError("FE Response"); + 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){ + LogHandler.logFeRequest(httpRequest); + inHttpRequest(httpRequest); + } + + private void logFeResponse(HttpServletRequest request, Response proxyResponse){ + LogHandler.logFeResponse(request); + outHttpResponse(proxyResponse); + } + + // Extracted for purpose of clear method name, for logback %M parameter + private void inHttpRequest(HttpServletRequest httpRequest) { + log.info("{} {} {}", httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getProtocol()); + } + + // Extracted for purpose of clear method name, for logback %M parameter + private void outHttpResponse(Response proxyResponse) { + log.info("SC=\"{}\"", proxyResponse.getStatus()); + } + + private String getModifiedUrl(Configuration config, PluginsConfiguration pluginConf, String uri, String queryString) throws MalformedURLException{ + if (config == null) { + log.error(EcompLoggerErrorCode.UNKNOWN_ERROR,"FeProxyServlet getModifiedUrl", "sdc-FE", "failed to retrieve configuration."); + throw new RuntimeException("failed to read FE configuration"); + } + String protocol; + String host; + String port; + if (uri.contains(ONBOARDING_CONTEXT)){ + uri = uri.replace(SDC1_FE_PROXY+ONBOARDING_CONTEXT,ONBOARDING_CONTEXT); + protocol = config.getOnboarding().getProtocolBe(); + host = config.getOnboarding().getHostBe(); + port = config.getOnboarding().getPortBe().toString(); + }else if(uri.contains(DCAED_CONTEXT)){ + uri = uri.replace(SDC1_FE_PROXY+DCAED_CONTEXT,DCAED_CONTEXT); + protocol = config.getBeProtocol(); + host = config.getBeHost(); + if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) { + port = config.getBeHttpPort().toString(); + } else { + port = config.getBeSslPort().toString(); + } + } + else if (uri.contains(WORKFLOW_CONTEXT)){ + uri = uri.replace(SDC1_FE_PROXY +WORKFLOW_CONTEXT,WORKFLOW_CONTEXT); + String workflowPluginURL = pluginConf.getPluginsList() + .stream() + .filter(plugin -> plugin.getPluginId().equalsIgnoreCase(PLUGIN_ID_WORKFLOW)) + .map(Plugin::getPluginDiscoveryUrl) + .findFirst().orElse(null); + + java.net.URL workflowURL = new URL(workflowPluginURL); + protocol = workflowURL.getProtocol(); + host = workflowURL.getHost(); + port = String.valueOf(workflowURL.getPort()); + } + else{ + uri = uri.replace(SDC1_FE_PROXY,"/sdc2"); + protocol = config.getBeProtocol(); + host = config.getBeHost(); + if (config.getBeProtocol().equals(BeProtocol.HTTP.getProtocolName())) { + port = config.getBeHttpPort().toString(); + } else { + port = config.getBeSslPort().toString(); + } + } + + String authority = getAuthority(host, port); + String modifiedUrl = String.format(URL,protocol,authority,uri); + if( !StringUtils.isEmpty(queryString)){ + modifiedUrl += "?" + queryString; + } + + return modifiedUrl; + + } + @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; + } + return authority; + } + + private String getQueryString(HttpServletRequest request){ + final String queryString = request.getQueryString(); + return StringUtils.isEmpty(queryString) ? StringUtils.EMPTY : queryString; + } + } diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/HealthCheckService.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/HealthCheckService.java deleted file mode 100644 index 6c312ceff7..0000000000 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/HealthCheckService.java +++ /dev/null @@ -1,361 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.fe.servlets; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonSyntaxException; -import com.google.gson.reflect.TypeToken; -import org.openecomp.sdc.common.api.HealthCheckInfo; -import org.openecomp.sdc.common.api.HealthCheckWrapper; -import org.openecomp.sdc.common.config.EcompErrorEnum; -import org.openecomp.sdc.common.http.client.api.HttpResponse; -import org.openecomp.sdc.common.http.config.HttpClientConfig; -import org.openecomp.sdc.common.http.config.Timeouts; -import org.openecomp.sdc.common.util.HealthCheckUtil; -import org.openecomp.sdc.fe.config.Configuration; -import org.openecomp.sdc.fe.config.ConfigurationManager; -import org.openecomp.sdc.fe.config.FeEcompErrorManager; -import org.slf4j.Logger; - -import javax.servlet.ServletContext; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import static java.util.Arrays.asList; -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; -import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR; -import static org.apache.http.HttpStatus.SC_OK; -import static org.openecomp.sdc.common.api.Constants.CONFIGURATION_MANAGER_ATTR; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_BE; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_CASSANDRA; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_DCAE; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_DISTRIBUTION_ENGINE; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_FE; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_JANUSGRAPH; -import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_ON_BOARDING; -import static org.openecomp.sdc.common.api.Constants.HTTPS; -import static org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus.DOWN; -import static org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus.UNKNOWN; -import static org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus.UP; -import static org.openecomp.sdc.common.http.client.api.HttpRequest.get; -import static org.openecomp.sdc.common.impl.ExternalConfiguration.getAppVersion; -import static org.slf4j.LoggerFactory.getLogger; - -public class HealthCheckService { - - private static final String URL = "%s://%s:%s/sdc2/rest/healthCheck"; - private static final int HEALTH_STATUS_CODE = 500; - private static Logger healthLogger = getLogger("asdc.fe.healthcheck"); - private static Logger log = getLogger(HealthCheckService.class.getName()); - private final List<String> healthCheckFeComponents = asList(HC_COMPONENT_ON_BOARDING, HC_COMPONENT_DCAE); - private static final HealthCheckUtil healthCheckUtil = new HealthCheckUtil(); - private static final String DEBUG_CONTEXT = "HEALTH_FE"; - /** - * This executor will execute the health check task. - */ - private ScheduledExecutorService healthCheckExecutor = newSingleThreadScheduledExecutor((Runnable r) -> new Thread(r, "FE-Health-Check-Thread")); - - public void setTask(HealthCheckScheduledTask task) { - this.task = task; - } - - private HealthCheckScheduledTask task; - private HealthStatus lastHealthStatus = new HealthStatus(HEALTH_STATUS_CODE, "{}"); - private ServletContext context; - - public HealthCheckService(ServletContext context) { - this.context = context; - this.task = new HealthCheckScheduledTask(); - } - - public void start(int interval) { - this.healthCheckExecutor.scheduleAtFixedRate(getTask(), 0, interval, TimeUnit.SECONDS); - } - - /** - * To be used by the HealthCheckServlet - * - * @return - */ - public Response getFeHealth() { - return this.buildResponse(lastHealthStatus.statusCode, lastHealthStatus.body); - } - - private Response buildResponse(int status, String jsonResponse) { - healthLogger.trace("FE and BE health check status: {}", jsonResponse); - return Response.status(status).entity(jsonResponse).build(); - } - - public HealthStatus getLastHealthStatus() { - return lastHealthStatus; - } - - public HealthCheckScheduledTask getTask() { - return task; - } - - //immutable - protected static class HealthStatus { - - private String body; - private int statusCode; - - public HealthStatus(int code, String body) { - this.body = body; - this.statusCode = code; - } - - public int getStatusCode() { - return statusCode; - } - - public String getBody() { - return body; - } - } - - protected class HealthCheckScheduledTask implements Runnable { - - public static final int READ_TIMEOUT_DEFAULT_VAL = 5000; - public static final int CONNECT_TIMEOUT_MS = 3000; - - @Override - public void run() { - healthLogger.trace("Executing FE Health Check Task - Start"); - HealthStatus currentHealth = checkHealth(); - int currentHealthStatus = currentHealth.statusCode; - healthLogger.trace("Executing FE Health Check Task - Status = {}", currentHealthStatus); - - // In case health status was changed, issue alarm/recovery - if (currentHealthStatus != lastHealthStatus.statusCode) { - log.trace("FE Health State Changed to {}. Issuing alarm / recovery alarm...", currentHealthStatus); - logFeAlarm(currentHealthStatus); - } - - // Anyway, update latest response - lastHealthStatus = currentHealth; - } - - private List<HealthCheckInfo> addHostedComponentsFeHealthCheck(String baseComponent) { - Configuration config = getConfig(); - - String healthCheckUrl = null; - switch (baseComponent) { - case HC_COMPONENT_ON_BOARDING: - healthCheckUrl = buildOnboardingHealthCheckUrl(config); - break; - case HC_COMPONENT_DCAE: - healthCheckUrl = buildDcaeHealthCheckUrl(config); - break; - default: - log.debug("Unsupported base component {}", baseComponent); - } - - StringBuilder description = new StringBuilder(""); - int connectTimeoutMs = CONNECT_TIMEOUT_MS; - int readTimeoutMs = config.getHealthCheckSocketTimeoutInMs(READ_TIMEOUT_DEFAULT_VAL); - - if (healthCheckUrl != null) { - ObjectMapper mapper = new ObjectMapper(); - try { - HttpResponse<String> response = get(healthCheckUrl, new HttpClientConfig(new Timeouts(connectTimeoutMs, readTimeoutMs))); - int beStatus = response.getStatusCode(); - if (beStatus == SC_OK || beStatus == SC_INTERNAL_SERVER_ERROR) { - String beJsonResponse = response.getResponse(); - return convertResponse(beJsonResponse, mapper, baseComponent, description, beStatus); - } else { - description.append("Response code: " + beStatus); - log.trace("{} Health Check Response code: {}", baseComponent, beStatus); - } - } catch (Exception e) { - log.error("{} Unexpected response ", baseComponent, e); - description.append(baseComponent + " Unexpected response: " + e.getMessage()); - } - } else { - description.append(baseComponent + " health check Configuration is missing"); - } - - return asList(new HealthCheckInfo(HC_COMPONENT_FE, DOWN, null, description.toString())); - } - - private void logFeAlarm(int lastFeStatus) { - switch (lastFeStatus) { - case SC_OK: - FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT, EcompErrorEnum.FeHealthCheckRecovery, "FE Health Recovered"); - FeEcompErrorManager.getInstance().logFeHealthCheckRecovery("FE Health Recovered"); - break; - case SC_INTERNAL_SERVER_ERROR: - FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT, EcompErrorEnum.FeHealthCheckError, "Connection with ASDC-BE is probably down"); - FeEcompErrorManager.getInstance().logFeHealthCheckError("Connection with ASDC-BE is probably down"); - break; - default: - break; - } - } - - protected HealthStatus checkHealth() { - HttpResponse<String> response; - try { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - Configuration config = getConfig(); - String redirectedUrl = String.format(URL, config.getBeProtocol(), config.getBeHost(), - HTTPS.equals(config.getBeProtocol()) ? config.getBeSslPort() : config.getBeHttpPort()); - - int connectTimeoutMs = CONNECT_TIMEOUT_MS; - int readTimeoutMs = config.getHealthCheckSocketTimeoutInMs(READ_TIMEOUT_DEFAULT_VAL); - - HealthCheckWrapper feAggHealthCheck; - try { - response = get(redirectedUrl, new HttpClientConfig(new Timeouts(connectTimeoutMs, readTimeoutMs))); - log.debug("HC call to BE - status code is {}", response.getStatusCode()); - String beJsonResponse = response.getResponse(); - feAggHealthCheck = getFeHealthCheckInfos(gson, beJsonResponse); - } catch (Exception e) { - log.debug("Health Check error when trying to connect to BE or external FE. Error: {}", e.getMessage()); - log.error("Health Check error when trying to connect to BE or external FE.", e); - String beDowneResponse = gson.toJson(getBeDownCheckInfos()); - return new HealthStatus(SC_INTERNAL_SERVER_ERROR, beDowneResponse); - } - - //Getting aggregate FE status - boolean aggregateFeStatus = (response != null && response.getStatusCode() == SC_INTERNAL_SERVER_ERROR) ? false : healthCheckUtil.getAggregateStatus(feAggHealthCheck.getComponentsInfo(), config.getHealthStatusExclude()); - return new HealthStatus(aggregateFeStatus ? SC_OK : SC_INTERNAL_SERVER_ERROR, gson.toJson(feAggHealthCheck)); - } catch (Exception e) { - FeEcompErrorManager.getInstance().processEcompError(DEBUG_CONTEXT, EcompErrorEnum.FeHealthCheckGeneralError, "Unexpected FE Health check error"); - FeEcompErrorManager.getInstance().logFeHealthCheckGeneralError("Unexpected FE Health check error"); - log.error("Unexpected FE health check error {}", e.getMessage()); - return new HealthStatus(SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - protected Configuration getConfig() { - return ((ConfigurationManager) context.getAttribute(CONFIGURATION_MANAGER_ATTR)) - .getConfiguration(); - } - - protected HealthCheckWrapper getFeHealthCheckInfos(Gson gson, String responseString) { - Configuration config = getConfig(); - Type wrapperType = new TypeToken<HealthCheckWrapper>() { - }.getType(); - HealthCheckWrapper healthCheckWrapper = gson.fromJson(responseString, wrapperType); - String appVersion = getAppVersion(); - String description = "OK"; - healthCheckWrapper.getComponentsInfo() - .add(new HealthCheckInfo(HC_COMPONENT_FE, UP, appVersion, description)); - - //add hosted components fe component - for (String component : healthCheckFeComponents) { - List<HealthCheckInfo> feComponentsInfo = addHostedComponentsFeHealthCheck(component); - HealthCheckInfo baseComponentHCInfo = healthCheckWrapper.getComponentsInfo().stream().filter(c -> c.getHealthCheckComponent().equals(component)).findFirst().orElse(null); - if (baseComponentHCInfo != null) { - if (baseComponentHCInfo.getComponentsInfo() == null) { - baseComponentHCInfo.setComponentsInfo(new ArrayList<>()); - } - baseComponentHCInfo.getComponentsInfo().addAll(feComponentsInfo); - boolean status = healthCheckUtil.getAggregateStatus(baseComponentHCInfo.getComponentsInfo(), config.getHealthStatusExclude()); - baseComponentHCInfo.setHealthCheckStatus(status ? UP : DOWN); - - String componentsDesc = healthCheckUtil.getAggregateDescription(baseComponentHCInfo.getComponentsInfo(), baseComponentHCInfo.getDescription()); - if (componentsDesc.length() > 0) { //aggregated description contains all the internal components desc - baseComponentHCInfo.setDescription(componentsDesc); - } - } else { - log.error("{} not exists in HealthCheck info", component); - } - } - return healthCheckWrapper; - } - - private HealthCheckWrapper getBeDownCheckInfos() { - List<HealthCheckInfo> healthCheckInfos = new ArrayList<>(); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_FE, UP, - getAppVersion(), "OK")); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_BE, DOWN, null, null)); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_JANUSGRAPH, UNKNOWN, null, null)); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_CASSANDRA, UNKNOWN, null, null)); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_DISTRIBUTION_ENGINE, UNKNOWN, null, null)); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_ON_BOARDING, UNKNOWN, null, null)); - healthCheckInfos.add(new HealthCheckInfo(HC_COMPONENT_DCAE, UNKNOWN, null, null)); - return new HealthCheckWrapper(healthCheckInfos, "UNKNOWN", "UNKNOWN"); - } - - private String buildOnboardingHealthCheckUrl(Configuration config) { - - Configuration.OnboardingConfig onboardingConfig = config.getOnboarding(); - - if (onboardingConfig != null) { - String protocol = onboardingConfig.getProtocolFe(); - String host = onboardingConfig.getHostFe(); - Integer port = onboardingConfig.getPortFe(); - String uri = onboardingConfig.getHealthCheckUriFe(); - - return protocol + "://" + host + ":" + port + uri; - } - - log.error("onboarding health check configuration is missing."); - return null; - } - - private String buildDcaeHealthCheckUrl(Configuration config) { - - Configuration.DcaeConfig dcaeConfig = config.getDcae(); - - if (dcaeConfig != null) { - String protocol = dcaeConfig.getProtocol(); - String host = dcaeConfig.getHost(); - Integer port = dcaeConfig.getPort(); - String uri = dcaeConfig.getHealthCheckUri(); - - return protocol + "://" + host + ":" + port + uri; - } - - log.error("dcae health check configuration is missing."); - return null; - } - - private List<HealthCheckInfo> convertResponse(String beJsonResponse, ObjectMapper mapper, String baseComponent, StringBuilder description, int beStatus) { - try { - Map<String, Object> healthCheckMap = mapper.readValue(beJsonResponse, new TypeReference<Map<String, Object>>() { - }); - if (healthCheckMap.containsKey("componentsInfo")) { - return mapper.convertValue(healthCheckMap.get("componentsInfo"), new TypeReference<List<HealthCheckInfo>>() { - }); - } else { - description.append("Internal components are missing"); - } - } catch (JsonSyntaxException | IOException e) { - log.error("{} Unexpected response body ", baseComponent, e); - description.append(baseComponent + " Unexpected response body. Response code: " + beStatus); - } - return new ArrayList<>(); - } - } - -} diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/KibanaServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/KibanaServlet.java deleted file mode 100644 index 1c6a575087..0000000000 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/KibanaServlet.java +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright (c) 2019 Samsung - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.fe.servlets; - -import org.eclipse.jetty.proxy.ProxyServlet; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.fe.config.Configuration; -import org.openecomp.sdc.fe.config.ConfigurationManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.http.HttpServletRequest; - -public class KibanaServlet extends ProxyServlet { - - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = LoggerFactory.getLogger(KibanaServlet.class.getName()); - - @Override - public String rewriteTarget(HttpServletRequest request) { - String originalUrl = request.getRequestURI(); - String redirectedUrl = getModifiedUrl(request); - - LOGGER.debug("KibanaServlet Redirecting request from: {} , to: {}", originalUrl, redirectedUrl); - - return redirectedUrl; - } - - public String getModifiedUrl(HttpServletRequest request) { - Configuration config = getConfiguration(request); - - if (config == null) { - LOGGER.error("Failed to retrieve configuration."); - throw new NullPointerException("Failed to retrieve configuration."); - } - - String contextPath = request.getContextPath(); - String servletPath = request.getServletPath(); - String pathInfo = request.getPathInfo(); - String queryString = request.getQueryString(); - - StringBuilder url = new StringBuilder(); - url.append(config.getKibanaProtocol()).append("://").append(config.getKibanaHost()); - url.append(":").append(config.getKibanaPort()); - url.append(contextPath).append(servletPath); - - if (pathInfo != null) { - url.append(pathInfo); - } - - if (queryString != null) { - url.append("?").append(queryString); - } - - return url.toString().replace("/sdc1/kibanaProxy/", "/"); - } - - private Configuration getConfiguration(HttpServletRequest request) { - return ((ConfigurationManager) request.getSession().getServletContext() - .getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).getConfiguration(); - } -} diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/LoggingServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/LoggingServlet.java index 3cb601fc3c..4bcbaa531b 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/LoggingServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/LoggingServlet.java @@ -20,107 +20,46 @@ package org.openecomp.sdc.fe.servlets; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.servlets.BasicServlet; -import org.openecomp.sdc.fe.impl.MdcData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; +import org.openecomp.sdc.fe.impl.LogHandler; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; -import java.util.concurrent.TimeUnit; public abstract class LoggingServlet extends BasicServlet { - private static final int EXPIRE_DURATION = 10; - private static final Cache<String, MdcData> mdcDataCache = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_DURATION, TimeUnit.SECONDS).build(); + public static final String UUID = "uuid"; + public static final String TRANSACTION_START_TIME = "transactionStartTime"; /** * log incoming requests - * * @param httpRequest the http request */ - protected void logFeRequest(HttpServletRequest httpRequest) { - - MDC.clear(); - - Long transactionStartTime = System.currentTimeMillis(); - 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) { - 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); - } + void logFeRequest(HttpServletRequest httpRequest){ + LogHandler.logFeRequest(httpRequest); inHttpRequest(httpRequest); } /** * log response - * - * @param request orig request + * @param request orig request * @param response returned response */ - protected void logFeResponse(HttpServletRequest request, Response response) { - 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); - } - } + void logFeResponse(HttpServletRequest request, Response response) { + LogHandler.logFeResponse(request); outHttpResponse(response); - - MDC.clear(); } /** * Extracted for purpose of clear method name, for logback %M parameter - * * @param httpRequest http request */ - protected abstract void inHttpRequest(HttpServletRequest httpRequest); + protected abstract void inHttpRequest(HttpServletRequest httpRequest) ; /** * Extracted for purpose of clear method name, for logback %M parameter - * * @param response http response */ protected abstract void outHttpResponse(Response response); - - /** - * update mdc with values from the request - * - * @param uuid service uuid - * @param serviceInstanceID serviceInstanceID - * @param userId userId - * @param remoteAddr remoteAddr - * @param localAddr localAddr - * @param transactionStartTime transactionStartTime - */ - 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); - } } diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/PortalServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/PortalServlet.java index d72268314a..cb4b901ac6 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/PortalServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/PortalServlet.java @@ -22,13 +22,14 @@ package org.openecomp.sdc.fe.servlets; import org.onap.portalsdk.core.onboarding.exception.CipherUtilException; import org.onap.portalsdk.core.onboarding.util.CipherUtil; +import org.onap.sdc.security.AuthenticationCookie; +import org.onap.sdc.security.RepresentationUtils; import org.openecomp.sdc.common.impl.MutableHttpServletRequest; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.fe.Constants; import org.openecomp.sdc.fe.config.Configuration; import org.openecomp.sdc.fe.config.ConfigurationManager; import org.openecomp.sdc.fe.config.FeEcompErrorManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -49,12 +50,14 @@ import java.util.List; @Path("/") public class PortalServlet extends HttpServlet { - private static Logger log = LoggerFactory.getLogger(PortalServlet.class.getName()); + private static Logger log = Logger.getLogger(PortalServlet.class.getName()); private static final long serialVersionUID = 1L; + public static final String MISSING_HEADERS_MSG = "Missing Headers In Request"; private static final String AUTHORIZATION_ERROR_MSG = "Autherization error"; private static final String NEW_LINE = System.getProperty("line.separator"); + /** * Entry point from ECOMP portal */ @@ -91,6 +94,8 @@ public class PortalServlet extends HttpServlet { // Check if we got header from webseal String userId = request.getHeader(Constants.WEBSEAL_USER_ID_HEADER); + String firstNameFromCookie = ""; + String lastNameFromCookie = ""; if (null == userId) { // Authentication via ecomp portal try { @@ -109,6 +114,10 @@ public class PortalServlet extends HttpServlet { // Replace webseal header with open source header mutableRequest.putHeader(Constants.USER_ID, userId); + + + + // Getting identification headers from configuration.yaml // (identificationHeaderFields) and setting them to new request // mutableRequest @@ -139,6 +148,10 @@ public class PortalServlet extends HttpServlet { if (allHeadersExist) { addCookies(response, mutableRequest, getMandatoryHeaders(request)); addCookies(response, mutableRequest, getOptionalHeaders(request)); + firstNameFromCookie = getValueFromCookie(request, Constants.HTTP_CSP_FIRSTNAME ); + lastNameFromCookie = getValueFromCookie(request, Constants.HTTP_CSP_LASTNAME); + + addAuthCookie(response, userId, firstNameFromCookie, lastNameFromCookie); RequestDispatcher rd = request.getRequestDispatcher("index.html"); rd.forward(mutableRequest, response); } else { @@ -146,6 +159,39 @@ public class PortalServlet extends HttpServlet { } } + boolean addAuthCookie(HttpServletResponse response, String userId, String firstName, String lastName) throws IOException { + boolean isBuildCookieCompleted = true; + AuthenticationCookie authenticationCookie = null; + Cookie authCookie = null; + Configuration.CookieConfig confCookie = + ConfigurationManager.getConfigurationManager().getConfiguration().getAuthCookie(); + + //create authentication and send it to encryption + + String encryptedCookie = ""; + try { + authenticationCookie = new AuthenticationCookie(userId, firstName, lastName); + String cookieAsJson = RepresentationUtils.toRepresentation(authenticationCookie); + encryptedCookie = org.onap.sdc.security.CipherUtil.encryptPKC(cookieAsJson, confCookie.getSecurityKey()); + } catch (Exception e) { + isBuildCookieCompleted=false; + log.error(" Cookie Encryption failed ", e); + } + + authCookie = new Cookie(confCookie.getCookieName(), encryptedCookie); + authCookie.setPath(confCookie.getPath()); + authCookie.setDomain(confCookie.getDomain()); + authCookie.setHttpOnly(true); + + // add generated cookie to response + if (isBuildCookieCompleted) { + response.addCookie(authCookie); + return true; + } + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, AUTHORIZATION_ERROR_MSG); + return false; + } + /** * Print all request headers to the log * @@ -182,6 +228,7 @@ public class PortalServlet extends HttpServlet { /** * Add cookies (that where set in the new request headers) in the response + * Using DefaultHTTPUtilities Object to prevent CRLF injection in HTTP headers. * * @param response * @param request @@ -292,6 +339,22 @@ public class PortalServlet extends HttpServlet { userId = CipherUtil.decrypt(userIdcookie.getValue()); } return userId; + } + + private static String getValueFromCookie(HttpServletRequest request, String cookieName) { + String value = ""; + Cookie[] cookies = request.getCookies(); + Cookie valueFromCookie = null; + if (cookies != null) + for (Cookie cookie : cookies) { + if (cookie.getName().endsWith(cookieName)) { + valueFromCookie = cookie; + } + } + if (valueFromCookie != null) { + value = valueFromCookie.getValue(); + } + return value; } } diff --git a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/SSLProxyServlet.java b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/SSLProxyServlet.java index 25659ddd92..d4f6832dba 100644 --- a/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/SSLProxyServlet.java +++ b/catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/SSLProxyServlet.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |