diff options
author | ys9693 <ys9693@att.com> | 2020-01-19 13:50:02 +0200 |
---|---|---|
committer | Ofir Sonsino <ofir.sonsino@intl.att.com> | 2020-01-22 12:33:31 +0000 |
commit | 16a9fce0e104a38371a9e5a567ec611ae3fc7f33 (patch) | |
tree | 03a2aff3060ddb5bc26a90115805a04becbaffc9 /catalog-fe | |
parent | aa83a2da4f911c3ac89318b8e9e8403b072942e1 (diff) |
Catalog alignment
Issue-ID: SDC-2724
Signed-off-by: ys9693 <ys9693@att.com>
Change-Id: I52b4aacb58cbd432ca0e1ff7ff1f7dd52099c6fe
Diffstat (limited to 'catalog-fe')
45 files changed, 2385 insertions, 1331 deletions
diff --git a/catalog-fe/pom.xml b/catalog-fe/pom.xml index a6016c47d8..983f48b3dc 100644 --- a/catalog-fe/pom.xml +++ b/catalog-fe/pom.xml @@ -28,13 +28,6 @@ <dependency> <groupId>org.openecomp.sdc</groupId> - <artifactId>security-utils</artifactId> - <version>${project.version}</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>org.openecomp.sdc</groupId> <artifactId>common-app-api</artifactId> <version>${project.version}</version> </dependency> diff --git a/catalog-fe/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-configuration.yaml.erb b/catalog-fe/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-configuration.yaml.erb index 4b64df3101..d97abdefd2 100644 --- a/catalog-fe/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-configuration.yaml.erb +++ b/catalog-fe/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-configuration.yaml.erb @@ -26,6 +26,14 @@ threadpoolSize: 50 # request processing timeout (seconds) requestTimeout: 10 +# catalog ms (the host-port values need to be changed once it is deployed) +catalogFacadeMs: + protocol: http + host: <%= node['FACADE_VIP'] %> + port: <%= @facade_port %> + healthCheckUri: "/healthCheck" + path: "/uicache" + # Determines the health check read timeout when invoking health check towards the LB (or BE whatever is configured): healthCheckSocketTimeoutInMs: 5000 @@ -89,6 +97,14 @@ optionalHeaderFields: version: 1.0 released: 2012-11-30 +# access restriction +authCookie: + cookieName: "AuthenticationCookie" + path: / + domain: "" + securityKey: <%= node['access_restriction_key'] %> + + # Connection parameters connection: url: jdbc:mysql://localhost:3306/db @@ -105,11 +121,10 @@ systemMonitoring: isProxy: true probeIntervalInSeconds: 15 -kibanaHost: <%= @kb_host_ip %> -kibanaPort: 5601 -kibanaProtocol: http healthStatusExclude: - DE - DMAAP - DCAE + - DMAAP_PRODUCER + - PORTAL 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. diff --git a/catalog-fe/src/main/resources/config/configuration.yaml b/catalog-fe/src/main/resources/config/configuration.yaml index d1156da771..2eff183e1a 100644 --- a/catalog-fe/src/main/resources/config/configuration.yaml +++ b/catalog-fe/src/main/resources/config/configuration.yaml @@ -22,6 +22,14 @@ threadpoolSize: 50 # request processing timeout (seconds) requestTimeout: 10 +# catalog ms (the host-port values need to be changed once it is deployed) +catalogFacadeMs: + protocol: http + host: 192.168.33.10 + port: 8282 + healthCheckUri: "/healthCheck" + path: "/uicache" + # Determines the health check read timeout when invoking health check towards the LB (or BE whatever is configured): healthCheckSocketTimeoutInMs: 5000 healthCheckIntervalInSeconds: 5 @@ -71,6 +79,13 @@ optionalHeaderFields: - &HTTP_CSP_EMAIL HTTP_CSP_EMAIL - &csp-email csp-email +# access restriction +authCookie: + cookieName: "AuthenticationCookie" + path: / + domain: "" + securityKey: "AGLDdG4D04BKm2IxIWEr8o==" + version: 1.0 released: 2012-11-30 @@ -90,11 +105,9 @@ systemMonitoring: isProxy: true probeIntervalInSeconds: 15 -kibanaHost: localhost -kibanaPort: 5601 -kibanaProtocol: http healthStatusExclude: - DE - ES - DMAAP + - DMAAP_PRODUCER diff --git a/catalog-fe/src/main/resources/config/logback.xml b/catalog-fe/src/main/resources/config/logback.xml index d1e1c613d1..d7c9c7e527 100644 --- a/catalog-fe/src/main/resources/config/logback.xml +++ b/catalog-fe/src/main/resources/config/logback.xml @@ -1,125 +1,130 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="5 seconds"> - <property scope="system" name="ECOMP-component-name" value="SDC" /> - <property scope="system" name="ECOMP-subcomponent-name" value="SDC-FE" /> - <property scope="context" name="enable-all-log" value="false" /> - <property file="${config.home}/catalog-fe/configuration.yaml" /> - <!-- value used by pattern field list (| - is inter-field separator, || - unavailable or not applicable field value) (m - mandatory, o- optional)--> - <!--timestamp(m)| requestID(m)| serviceInstanceID(o)| threadID(m)| physicalServerName(o)| serviceName(m)| userID(m)| logLevel(m)| severity(o)| serverIpAddress(m)| serverName(m)| clientIpAddress(o)| className(m)| timer(o)| detailedMessage(o)--> - <property name="default-log-pattern" - value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{uuid}|%X{serviceInstanceID}|%thread||${ECOMP-subcomponent-name}|%X{userId}|%level|%X{alarmSeverity}|%X{localAddr}|${feFqdn}|%X{remoteAddr}|%logger{35}|%X{timer}|ActivityType=<%M>, Desc=<%msg>%n" /> - - <!-- All log --> - <if condition='property("enable-all-log").equalsIgnoreCase("true")'> - <then> - <appender name="ALL_ROLLING" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log - </file> - - <rollingPolicy - class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log.%i - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>10</maxIndex> - </rollingPolicy> - - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>20MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${default-log-pattern}</pattern> - </encoder> - </appender> - - <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"> - <appender-ref ref="ALL_ROLLING" /> - </appender> - - </then> - </if> - - <!-- Error log --> - <appender name="ERROR_ROLLING" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log - </file> - - <!-- deny all events with a level below INFO, that is TRACE and DEBUG --> - <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> - <level>INFO</level> - </filter> - - <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log.%i - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>10</maxIndex> - </rollingPolicy> - - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>20MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${default-log-pattern}</pattern> - </encoder> - </appender> - - <!-- Debug log --> - <appender name="DEBUG_ROLLING" - class="ch.qos.logback.core.rolling.RollingFileAppender"> - <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log - </file> - - <!-- accept DEBUG and TRACE level --> - <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> - <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> - <expression> - e.level.toInt() <= DEBUG.toInt() - </expression> - </evaluator> - <OnMismatch>DENY</OnMismatch> - <OnMatch>NEUTRAL</OnMatch> - </filter> - - <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log.%i - </fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>10</maxIndex> - </rollingPolicy> - - <triggeringPolicy - class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>20MB</maxFileSize> - </triggeringPolicy> - <encoder> - <pattern>${default-log-pattern}</pattern> - </encoder> - </appender> - - <!-- Asynchronicity Configurations --> - <appender name="ASYNC_DEBUG" class="ch.qos.logback.classic.AsyncAppender"> - <appender-ref ref="DEBUG_ROLLING" /> - </appender> - - <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"> - <appender-ref ref="ERROR_ROLLING" /> - </appender> - - <root level="INFO"> - <appender-ref ref="ASYNC_ERROR" /> - <appender-ref ref="ASYNC_DEBUG" /> - <if condition='property("enable-all-log").equalsIgnoreCase("true")'> - <then> - <appender-ref ref="ALL_ROLLING" /> - </then> - </if> - </root> - - <logger name="org.openecomp.sdc" level="INFO" /> + <property scope="system" name="ECOMP-component-name" value="SDC"/> + <property scope="system" name="ECOMP-subcomponent-name" value="SDC-FE"/> + <property file="${config.home}/catalog-fe/configuration.yaml"/> + <property scope="context" name="enable-all-log" value="false"/> + <property name="p_msg" value="%replace(%replace(%replace(%replace(%msg){'\t','\\\\t'}){'\n', '\\\\n'}){'\\\|', '-'}){'\r','\\\\r'}"/> + <property name="p_ex" value="%replace(%replace(%replace(%replace(%exception{full}){'\t','\\\\t'}){'\n', '\\\\n'}){'\\\|', '-'}){'\r','\\\\r'}"/> + <property name="p_debugInfo" value="%replace(%replace(%replace(%replace(%thread # %level # %logger{35} # %msg){'\t','\\\\t'}){'\n', '\\\\n'}){'\\\|', '-'}){'\r','\\\\r'}"/> + + <property name="all-log-pattern" + value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{BeginTimestamp}|%X{EndTimestamp}|%X{uuid}|%X{serviceInstanceID}|%thread|%X{ServerName}|%X{ServiceName}|${ECOMP-subcomponent-name}|%X{userId}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceID}|%level|%X{alarmSeverity}|%X{localAddr}|%X{ElapsedTime}|${beFqdn}|%X{remoteAddr}|%logger{35}|%X{timer}|ActivityType=<%M>, Desc=<${p_msg}>%n"/> + + <property name="debug-log-pattern" + value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestID}|${p_debugInfo} ${p_ex}|^\n%n%nopex"/> + + <property name="error-log-pattern" + value="%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestID}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{ErrorCategory}|%X{ErrorCode}|${p_msg} ${p_ex}|%n%nopex"/> + + + <!-- All log --> + <if condition='property("enable-all-log").equalsIgnoreCase("true")'> + <then> + <appender name="ALL_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log</file> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern>${all-log-pattern}</pattern> + </encoder> + </appender> + </then> + </if> + + + <!-- Debug log --> + <appender name="DEBUG_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log</file> + + <!-- accept INFO, DEBUG and TRACE level --> + <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> + <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> + <expression> + e.level.toInt() <= INFO.toInt() + </expression> + </evaluator> + <OnMismatch>DENY</OnMismatch> + <OnMatch>ACCEPT</OnMatch> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern>${debug-log-pattern}</pattern> + </encoder> + </appender> + + + <!-- Error log --> + <appender name="ERROR_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log</file> + + <!-- deny all events with a level below WARN, that is INFO TRACE and DEBUG --> + <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> + <level>WARN</level> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern>${error-log-pattern}</pattern> + </encoder> + </appender> + + + <!-- Asynchronicity Configurations --> + <appender name="ASYNC_ALL" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="ALL_ROLLING"/> + </appender> + + <appender name="ASYNC_DEBUG" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="DEBUG_ROLLING"/> + </appender> + + <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="ERROR_ROLLING"/> + </appender> + + + <root level="INFO"> + <appender-ref ref="ASYNC_ERROR"/> + <appender-ref ref="ASYNC_DEBUG"/> + <if condition='property("enable-all-log").equalsIgnoreCase("true")'> + <then> + <appender-ref ref="ASYNC_ALL"/> + </then> + </if> + </root> + + <logger name="org.openecomp.sdc" level="INFO"/> </configuration>
\ No newline at end of file diff --git a/catalog-fe/src/main/resources/config/plugins-configuration.yaml b/catalog-fe/src/main/resources/config/plugins-configuration.yaml new file mode 100644 index 0000000000..eb36945715 --- /dev/null +++ b/catalog-fe/src/main/resources/config/plugins-configuration.yaml @@ -0,0 +1,23 @@ +pluginsList: + - pluginId: DCAE + pluginDiscoveryUrl: http://localhost:8702/dcae + pluginSourceUrl: http://localhost:8702/dcae + pluginStateUrl: "dcae" + pluginDisplayOptions: + context: + displayName: "Monitor" + displayContext: ["VF", "SERVICE"] + displayRoles: ["DESIGNER"] + - pluginId: WORKFLOW + pluginDiscoveryUrl: http://localhost:9527/ + pluginSourceUrl: http://localhost:9527/ + pluginStateUrl: "workflowDesigner" + pluginDisplayOptions: + top: + displayName: "WORKFLOW" + context: + displayName: "Workflow Designer" + displayContext: ["VF", "SERVICE"] + displayRoles: ["DESIGNER", "TESTER"] + +connectionTimeout: 1000
\ No newline at end of file diff --git a/catalog-fe/src/main/resources/portal.properties b/catalog-fe/src/main/resources/portal.properties index a146d6ef0c..d1b6d3a44e 100644 --- a/catalog-fe/src/main/resources/portal.properties +++ b/catalog-fe/src/main/resources/portal.properties @@ -5,8 +5,8 @@ ecomp_rest_url = https://ecomp.homer.att.com/ecompportal/auxapi portal.api.impl.class = org.openecomp.sdc.be.ecomp.EcompIntImpl # CSP-SSO URL -# ecomp_redirect_url = https://www.e-access.att.com/ecomp_portal_ist/ecompportal/process_csp -ecomp_redirect_url = http://127.0.0.1:8989/ECOMPPORTAL/login.htm +ecomp_redirect_url = https://www.e-access.att.com/ecomp_portal_qa/ecompportal/process_csp +#ecomp_redirect_url = http://127.0.0.1:8989/ECOMPPORTAL/login.htm # Cookie set by CSP-SSO csp_cookie_name = attESSec @@ -26,4 +26,6 @@ ueb_app_mailbox_name = app_topic_name_here # Consumer group name; most Apps should use {UUID} ueb_app_consumer_group_name = {UUID} -decryption_key = AGLDdG4D04BKm2IxIWEr8o==
\ No newline at end of file +decryption_key = AGLDdG4D04BKm2IxIWEr8o== + +portal_cookie_name = EPService
\ No newline at end of file diff --git a/catalog-fe/src/main/resources/scripts/install.sh b/catalog-fe/src/main/resources/scripts/install.sh index bed9411795..48f9a36001 100644 --- a/catalog-fe/src/main/resources/scripts/install.sh +++ b/catalog-fe/src/main/resources/scripts/install.sh @@ -48,10 +48,6 @@ exitOnError $? "copy_jvm_properties" ./scripts/updateSslParams.sh ${JETTY_BASE} exitOnError $? "updateSslParams_script" - -#ONLY FOR BE -#cp /opt/app/sdc/config/catalog-${COMP}/elasticsearch.yml config -#exitOnError $? "copy_elasticsearch_yaml_to_config" mkdir -p ${JETTY_BASE}/config/catalog-${COMP} cp -r /opt/app/sdc/config/catalog-${COMP}/*.xml ${JETTY_BASE}/config/catalog-${COMP} diff --git a/catalog-fe/src/main/webapp/WEB-INF/web.xml b/catalog-fe/src/main/webapp/WEB-INF/web.xml index 32680df234..1f259d9fde 100644 --- a/catalog-fe/src/main/webapp/WEB-INF/web.xml +++ b/catalog-fe/src/main/webapp/WEB-INF/web.xml @@ -65,28 +65,45 @@ <servlet-name>Portal</servlet-name> <url-pattern>/portal</url-pattern> </servlet-mapping> + - <!-- Kibana proxy --> - <servlet> - <servlet-name>KibanaProxy</servlet-name> - <servlet-class>org.openecomp.sdc.fe.servlets.KibanaServlet</servlet-class> - <load-on-startup>1</load-on-startup> + <filter> + <filter-name>AuditLogServletFilter</filter-name> + <filter-class>org.onap.logging.filter.base.AuditLogServletFilter</filter-class> <async-supported>true</async-supported> - </servlet> + </filter> + + <filter> + <filter-name>SecurityFilter</filter-name> + <filter-class>org.openecomp.sdc.fe.filters.SecurityFilter</filter-class> + <async-supported>true</async-supported> + <init-param> + <param-name>excludedUrls</param-name> + <!-- Comma separated list of excluded servlet URLs --> + <param-value>/config,/configmgr,/rest</param-value> + </init-param> + </filter> - <servlet-mapping> - <servlet-name>KibanaProxy</servlet-name> - <url-pattern>/kibanaProxy/*</url-pattern> - </servlet-mapping> - <filter> <filter-name>gzipFilter</filter-name> - <filter-class>org.openecomp.sdc.fe.GzipFilter</filter-class> + <filter-class>org.openecomp.sdc.fe.filters.GzipFilter</filter-class> + <async-supported>true</async-supported> </filter> - <filter-mapping> - <filter-name>gzipFilter</filter-name> - <url-pattern>*.jsgz</url-pattern> - </filter-mapping> + + <filter-mapping> + <filter-name>AuditLogServletFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <filter-mapping> + <filter-name>SecurityFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <filter-mapping> + <filter-name>gzipFilter</filter-name> + <url-pattern>*.jsgz</url-pattern> + </filter-mapping> <listener> <listener-class>org.openecomp.sdc.fe.listen.FEAppContextListener</listener-class> diff --git a/catalog-fe/src/test/SpecRunner.html b/catalog-fe/src/test/SpecRunner.html index 19ae8e50ab..d2617c5b5c 100644 --- a/catalog-fe/src/test/SpecRunner.html +++ b/catalog-fe/src/test/SpecRunner.html @@ -1,20 +1,3 @@ -<!-- - ~ Copyright (C) 2018 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. - --> - - <!DOCTYPE HTML> <html> <head> diff --git a/catalog-fe/src/test/jasmine-standalone-2.0.0/SpecRunner.html b/catalog-fe/src/test/jasmine-standalone-2.0.0/SpecRunner.html index 4d3ff2e791..a0e39f4b0c 100644 --- a/catalog-fe/src/test/jasmine-standalone-2.0.0/SpecRunner.html +++ b/catalog-fe/src/test/jasmine-standalone-2.0.0/SpecRunner.html @@ -1,21 +1,3 @@ -<!-- - ~ Copyright (C) 2018 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. - --> - - - <!DOCTYPE HTML> <html> <head> diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/GzipFilterTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/GzipFilterTest.java index 95f48a1a61..b291cdac6f 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/GzipFilterTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/GzipFilterTest.java @@ -20,9 +20,10 @@ package org.openecomp.sdc.fe; -import javax.servlet.FilterConfig; - import org.junit.Test; +import org.openecomp.sdc.fe.filters.GzipFilter; + +import javax.servlet.FilterConfig; public class GzipFilterTest { diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/filters/SecurityFilterTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/filters/SecurityFilterTest.java new file mode 100644 index 0000000000..d750e35243 --- /dev/null +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/filters/SecurityFilterTest.java @@ -0,0 +1,125 @@ +/*- + * ============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.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + + +@RunWith(MockitoJUnitRunner.class) +public class SecurityFilterTest { + + private static final String excludedUrls = "/config,/configmgr,/rest/healthCheck"; + + @Mock + private HttpServletRequest request; + @Mock + private FilterChain filterChain; + @Mock + private FilterConfig filterConfig; + @Spy + private HttpServletResponse response; + + @InjectMocks + private SecurityFilter securityFilter = new SecurityFilter(); + + @Before + public void setUpClass() throws ServletException{ + when(filterConfig.getInitParameter(SecurityFilter.FILTER_EXLUDED_URLS_KEY)).thenReturn(excludedUrls); + securityFilter.init(filterConfig); + } + + @Test + public void redirectPortalRequestAsCookieIsNotFound() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/portal"); + when(request.getCookies()).thenReturn(getCookies(false)); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(1)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + @Test + public void redirectFeProxyRequestAsCookiesIsNull() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/feProxy"); + when(request.getCookies()).thenReturn(null); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(1)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + @Test + public void requestIsNotRedirectedAsItIsFromPortal() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/feProxy"); + when(request.getCookies()).thenReturn(getCookies(true)); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(0)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + @Test + public void requestIsNotRedirectedAsHcUrlIsExcluded() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/rest/healthCheck"); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(0)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + + @Test + public void requestIsNotRedirectedAsConfigUrlIsExcluded() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/config"); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(0)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + @Test + public void requestIsNotRedirectedForConfigMngrUrlIsExcluded() throws ServletException, IOException { + when(request.getServletPath()).thenReturn("/configmgr"); + securityFilter.doFilter(request, response, filterChain); + Mockito.verify(response, times(0)).sendRedirect(PortalApiProperties.getProperty(SecurityFilter.PORTAL_REDIRECT_URL_KEY)); + } + + + private Cookie[] getCookies(boolean isFromPortal) { + Cookie[] cookies = new Cookie [1]; + if (isFromPortal) { + cookies[0] = new Cookie(PortalApiProperties.getProperty(SecurityFilter.PORTAL_COOKIE_NAME_KEY), "aaa"); + } + else { + cookies[0] = new Cookie("someName", "aaa"); + } + return cookies; + } +} diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/AuditTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/AuditTest.java index 83bcaab871..c65d75bdab 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/AuditTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/AuditTest.java @@ -20,14 +20,6 @@ package org.openecomp.sdc.fe.impl; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; - import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -35,6 +27,14 @@ import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.common.api.Constants; import org.slf4j.Logger; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + @RunWith(MockitoJUnitRunner.class) public class AuditTest { diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTaskTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTaskTest.java new file mode 100644 index 0000000000..362d40cb29 --- /dev/null +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HealthCheckScheduledTaskTest.java @@ -0,0 +1,185 @@ +/*- + * ============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.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.fe.config.Configuration; + +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HealthCheckScheduledTaskTest { + + private static final String PROTOCOL = "http"; + private static final String HOST = "192.115.113.25"; + private static final Integer PORT = 8090; + private static final String URI = "/healthCheck"; + private static final String HC_URL = String.format("%s://%s:%s%s", PROTOCOL, HOST, PORT, URI); + + @Mock + private Configuration.CatalogFacadeMsConfig catalogFacadeMsConfig; + @Mock + private Configuration.DcaeConfig dcaeConfig; + @Mock + private Configuration.OnboardingConfig onboardingConfig; + @Mock + private Configuration configuration; + @Mock + private HealthCheckService healthCheckService; + + @InjectMocks + private HealthCheckScheduledTask healthCheckScheduledTask; + + @Before + public void setUp() { + healthCheckScheduledTask = new HealthCheckScheduledTask(healthCheckService); + initMocks(); + } + + @Test + public void getOnboardingUrlWhenConfigurationIsNotProvided() { + when(configuration.getOnboarding()).thenReturn(null); + assertNull(healthCheckScheduledTask.getExternalComponentHcUrl(Constants.HC_COMPONENT_ON_BOARDING)); + } + + @Test + public void getUrlForUnknownComponent() { + assertNull(healthCheckScheduledTask.getExternalComponentHcUrl("test")); + } + + @Test + public void getOnboardingUrlWhenConfigurationIsProvided() { + when(configuration.getOnboarding()).thenReturn(onboardingConfig); + assertNull(HealthCheckScheduledTask.getOnboardingHcUrl()); + healthCheckScheduledTask.getExternalComponentHcUrl(Constants.HC_COMPONENT_ON_BOARDING); + assertEquals(HC_URL, HealthCheckScheduledTask.getOnboardingHcUrl()); + } + + @Test + public void getCatalogFacadeMsUrlWhenConfigurationIsProvidedAndVerifyThatItIsCalculatedOnlyOnce() { + when(configuration.getCatalogFacadeMs()).thenReturn(catalogFacadeMsConfig); + assertNull(HealthCheckScheduledTask.getCatalogFacadeMsHcUrl()); + + HealthCheckScheduledTask healthCheckScheduledTaskSpy = Mockito.spy(healthCheckScheduledTask); + + healthCheckScheduledTaskSpy.getExternalComponentHcUrl(Constants.HC_COMPONENT_CATALOG_FACADE_MS); + assertEquals(HC_URL, HealthCheckScheduledTask.getCatalogFacadeMsHcUrl()); + //try to run again and verify that assignment is not recalled + healthCheckScheduledTaskSpy.getExternalComponentHcUrl(Constants.HC_COMPONENT_CATALOG_FACADE_MS); + verify(healthCheckScheduledTaskSpy, times(1)). + buildHealthCheckUrl(any(String.class), any(String.class), any(Integer.class), any(String.class)); + } + + @Test + public void getDcaeUrlWhenConfigurationIsProvided() { + when(configuration.getDcae()).thenReturn(dcaeConfig); + assertNull(HealthCheckScheduledTask.getDcaeHcUrl()); + healthCheckScheduledTask.getExternalComponentHcUrl(Constants.HC_COMPONENT_DCAE); + assertEquals(HC_URL, HealthCheckScheduledTask.getDcaeHcUrl()); + } + + @Test + public void getExcludedComponentListWhenCatalogFacadeMsConfigExists() { + when(configuration.getCatalogFacadeMs()).thenReturn(catalogFacadeMsConfig); + when(catalogFacadeMsConfig.getPath()).thenReturn("/uicache"); + when(configuration.getHealthStatusExclude()).thenReturn(Lists.newArrayList("DMAAP", "DCAE")); + assertFalse(healthCheckScheduledTask.getExcludedComponentList().contains(Constants.HC_COMPONENT_CATALOG_FACADE_MS)); + } + + @Test + public void getExcludedComponentListWhenCatalogFacadeMsConfigDoesNotExist() { + when(configuration.getCatalogFacadeMs()).thenReturn(null); + when(configuration.getHealthStatusExclude()).thenReturn(Lists.newArrayList()); + assertTrue(healthCheckScheduledTask.getExcludedComponentList().contains(Constants.HC_COMPONENT_CATALOG_FACADE_MS)); + } + + @Test + public void getExcludedComponentListWhenCatalogFacadeMsConfigPathIsNotSet() { + when(configuration.getCatalogFacadeMs()).thenReturn(catalogFacadeMsConfig); + when(catalogFacadeMsConfig.getPath()).thenReturn(null); + when(configuration.getHealthStatusExclude()).thenReturn(Lists.newArrayList()); + assertTrue(healthCheckScheduledTask.getExcludedComponentList().contains(Constants.HC_COMPONENT_CATALOG_FACADE_MS)); + } + + @Test + public void getMergedHCListWhenFeHcIsEmptyAndMainListIsSet() { + HealthCheckInfo mainHC = new HealthCheckInfo(); + mainHC.setComponentsInfo(Collections.emptyList()); + assertEquals(0, healthCheckScheduledTask.updateSubComponentsInfoOfBeHc(mainHC, Collections.emptyList()).getComponentsInfo().size()); + } + + @Test + public void getMergedHCListWhenFeHcIsEmptyAndMainListIsNotSet() { + assertNull(healthCheckScheduledTask.updateSubComponentsInfoOfBeHc(new HealthCheckInfo(), Collections.emptyList()).getComponentsInfo()); + } + + @Test + public void getMergedHCListWhenFeHcListAndMainListAreNotEmpty() { + HealthCheckInfo mainHC = new HealthCheckInfo(); + mainHC.setComponentsInfo(Lists.newArrayList(new HealthCheckInfo())); + assertEquals(2, healthCheckScheduledTask.updateSubComponentsInfoOfBeHc(mainHC, + Collections.singletonList(new HealthCheckInfo())).getComponentsInfo().size()); + } + + @Test + public void getMergedHCListWhenFeHcListIsNotEmptyAndMainListIsEmpty() { + assertEquals(1, healthCheckScheduledTask.updateSubComponentsInfoOfBeHc(new HealthCheckInfo(), + Collections.singletonList(new HealthCheckInfo())).getComponentsInfo().size()); + } + + + private void initMocks() { + when(healthCheckService.getConfig()).thenReturn(configuration); + + when(onboardingConfig.getProtocolFe()).thenReturn(PROTOCOL); + when(onboardingConfig.getHostFe()).thenReturn(HOST); + when(onboardingConfig.getPortFe()).thenReturn(PORT); + when(onboardingConfig.getHealthCheckUriFe()).thenReturn(URI); + + when(dcaeConfig.getProtocol()).thenReturn(PROTOCOL); + when(dcaeConfig.getHost()).thenReturn(HOST); + when(dcaeConfig.getPort()).thenReturn(PORT); + when(dcaeConfig.getHealthCheckUri()).thenReturn(URI); + + when(catalogFacadeMsConfig.getProtocol()).thenReturn(PROTOCOL); + when(catalogFacadeMsConfig.getHost()).thenReturn(HOST); + when(catalogFacadeMsConfig.getPort()).thenReturn(PORT); + when(catalogFacadeMsConfig.getHealthCheckUri()).thenReturn(URI); + } +} diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HttpRequestInfoTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HttpRequestInfoTest.java index bfc45528c4..156e1624c4 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HttpRequestInfoTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/HttpRequestInfoTest.java @@ -22,12 +22,6 @@ package org.openecomp.sdc.fe.impl; -import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -36,6 +30,13 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; + @RunWith(MockitoJUnitRunner.class) public class HttpRequestInfoTest { diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/ImportMetadataTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/ImportMetadataTest.java index 2fd5b56b18..cb1beda053 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/ImportMetadataTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/ImportMetadataTest.java @@ -21,12 +21,12 @@ */ package org.openecomp.sdc.fe.impl; +import org.junit.Test; + import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; -import org.junit.Test; - public class ImportMetadataTest { private static final String CHECKSUM = "CHECKSUM"; diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/MdcDataTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/MdcDataTest.java index d07470668e..a967f46a8e 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/MdcDataTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/impl/MdcDataTest.java @@ -21,10 +21,10 @@ */ package org.openecomp.sdc.fe.impl; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class MdcDataTest { private static final String INSTANCE_ID = "INSTANCE_ID"; diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/listen/MyObjectMapperProviderTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/listen/MyObjectMapperProviderTest.java index 4a390d3e0c..63e978d807 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/listen/MyObjectMapperProviderTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/listen/MyObjectMapperProviderTest.java @@ -23,11 +23,11 @@ package org.openecomp.sdc.fe.listen; import com.fasterxml.jackson.core.JsonProcessingException; -import java.io.Serializable; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Assert; import org.junit.Test; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.Serializable; public class MyObjectMapperProviderTest { @@ -50,7 +50,7 @@ public class MyObjectMapperProviderTest { + "}"; ObjectMapper objectMapper = new MyObjectMapperProvider().getContext(MyObjectMapperProviderTest.class); - String serialized = objectMapper.writeValueAsString(new AnyModel("Field1")); + String serialized = objectMapper.writeValueAsString(new AnyModel("Field1")).replace("\r",""); Assert.assertEquals(serialized, prettyJson); } } diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigMgrServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigMgrServletTest.java index 5406863fc0..1030b9315e 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigMgrServletTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigMgrServletTest.java @@ -19,9 +19,6 @@ */ package org.openecomp.sdc.fe.servlets; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -34,6 +31,10 @@ import org.openecomp.sdc.common.rest.api.RestConfigurationInfo; import org.openecomp.sdc.fe.config.Configuration; import org.openecomp.sdc.fe.config.ConfigurationManager; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + @RunWith(MockitoJUnitRunner.class) public class ConfigMgrServletTest { diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigServletTest.java index 29a49bc611..1bc3a06e9a 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigServletTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/ConfigServletTest.java @@ -39,9 +39,7 @@ import javax.servlet.http.HttpSession; import javax.ws.rs.core.Response; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -104,19 +102,7 @@ public class ConfigServletTest { assertEquals(response.getStatus(), HttpStatus.SC_INTERNAL_SERVER_ERROR); } - @Test - public void validateGetPluginOnlineStateReturnsCorrectState() { - - final String testPluginName = "testPlugin"; - final String pluginAvailability = "forTesting"; - prepareMocks(); - when(pluginStatusBL.getPluginAvailability(eq(testPluginName))).thenReturn(pluginAvailability); - Response response = configServlet.getPluginOnlineState(testPluginName,httpServletRequest); - - assertEquals(response.getEntity().toString(),pluginAvailability); - assertEquals(response.getStatus(), HttpStatus.SC_OK); - } @Test public void validateGetPluginOnlineStateResponsesWithServerErrorIfExceptionIsThrown() { @@ -128,18 +114,7 @@ public class ConfigServletTest { assertEquals(response.getStatus(), HttpStatus.SC_INTERNAL_SERVER_ERROR); } - @Test - public void validateGetPluginOnlineStateResponsesWithNotFoundIfThereIsNoPlugin() { - - final String testPluginName = "testPlugin"; - prepareMocks(); - when(pluginStatusBL.getPluginAvailability(any(String.class))).thenReturn(null); - Response response = configServlet.getPluginOnlineState(testPluginName, httpServletRequest); - - assertEquals(response.getStatus(), HttpStatus.SC_NOT_FOUND); - assertTrue(response.getEntity().toString().contains(testPluginName)); - } private void prepareMocks() { when(httpServletRequest.getSession()).thenReturn(httpSession); diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServletTest.java index 78fe42ff8c..616e658d3e 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServletTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServletTest.java @@ -20,20 +20,21 @@ package org.openecomp.sdc.fe.servlets; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; -import static org.openecomp.sdc.common.api.Constants.HEALTH_CHECK_SERVICE_ATTR; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.fe.impl.HealthCheckService; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.ws.rs.core.Response; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.openecomp.sdc.common.api.Constants.HEALTH_CHECK_SERVICE_ATTR; @RunWith(MockitoJUnitRunner.class) public class FeHealthCheckServletTest { diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/servlets/FeProxyServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeProxyServletTest.java index 4915936b1d..36f218a391 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/servlets/FeProxyServletTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/FeProxyServletTest.java @@ -18,10 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.sdc.servlets; +package org.openecomp.sdc.fe.servlets; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpFields; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; @@ -29,16 +30,17 @@ import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.fe.config.Configuration; import org.openecomp.sdc.fe.config.ConfigurationManager; import org.openecomp.sdc.fe.config.PluginsConfiguration; -import org.openecomp.sdc.fe.servlets.FeProxyServlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @@ -57,6 +59,7 @@ public class FeProxyServletTest { final static ConfigurationManager configurationManager = Mockito.mock(ConfigurationManager.class); final static Configuration configuration = Mockito.mock(Configuration.class); final static Configuration.OnboardingConfig onboardingConfiguration = Mockito.mock(Configuration.OnboardingConfig.class); + private final static Configuration.CatalogFacadeMsConfig catalogFacadeMsConfig = Mockito.mock(Configuration.CatalogFacadeMsConfig.class); final static Request proxyRequest = Mockito.spy(Request.class); final static HttpFields httpFields = Mockito.mock(HttpFields.class); private static final PluginsConfiguration pluginsConfiguration = Mockito.mock(PluginsConfiguration.class); @@ -78,6 +81,12 @@ public class FeProxyServletTest { final static String HEADER_2_VAL = "Header2_Val"; final static String HEADER_3_VAL = "Header3_Val"; final static String REQUEST_ID_VAL = "4867495a-5ed7-49e4-8be2-cc8d66fdd52b"; + private final static String msProtocol = "http"; + private final static String msHealth = "/healthCheck"; + private final static String msHost = "localhost"; + private final static Integer msPort = 8080; + private final static String msPath = "/uicache"; + private final static String msUrl = String.format("%s://%s:%s", msProtocol, msHost, msPort); @BeforeClass public static void beforeClass() { @@ -93,7 +102,7 @@ public class FeProxyServletTest { when(configuration.getOnboarding().getHostBe()).thenReturn(ONBOARDING_BE_HOST); when(configuration.getOnboarding().getPortBe()).thenReturn(ONBOARDING_BE_PORT); - List<String> strList = new ArrayList<String>(); + List<String> strList = new ArrayList<>(); strList.add(HEADER_1); strList.add(HEADER_2); strList.add(HEADER_3); @@ -112,13 +121,19 @@ public class FeProxyServletTest { List<PluginsConfiguration.Plugin> pluginList = new ArrayList<PluginsConfiguration.Plugin>(); when(plugin.getPluginId()).thenReturn("WORKFLOW"); when(plugin.getPluginSourceUrl()).thenReturn(WF_PROTOCOL + "://" + WF_HOST + ":" + WF_PORT); - when(plugin.getPluginDiscoveryUrl()).thenReturn(WF_PROTOCOL + "://" + WF_HOST + ":" + WF_PORT + "/workflows"); + when(plugin.getPluginDiscoveryUrl()).thenReturn(WF_PROTOCOL + "://" + WF_HOST + ":" + WF_PORT); pluginList.add(plugin); when(configurationManager.getPluginsConfiguration()).thenReturn(pluginsConfiguration); when(pluginsConfiguration.getPluginsList()).thenReturn(pluginList); } + @Before + public void setUp() { + when(configuration.getCatalogFacadeMs()).thenReturn(catalogFacadeMsConfig); + when(servletRequest.getQueryString()).thenReturn(null); + when(catalogFacadeMsConfig.getPath()).thenReturn(null); + } @Test public void testRewriteURI_APIRequest() { when(servletRequest.getRequestURI()).thenReturn("/sdc1/feProxy/rest/dummyBeAPI"); @@ -180,11 +195,13 @@ public class FeProxyServletTest { assertTrue(rewriteURI.equals(expectedChangedUrl)); } + + @Test public void testRewriteURIWithWFAPIRequest() { when(servletRequest.getRequestURI()).thenReturn("/sdc1/feProxy/wf/workflows"); String requestResourceUrl = "http://localhost:8080/sdc1/feProxy/wf/workflows"; - String expectedChangedUrl = WF_PROTOCOL + "://" + WF_HOST + ":" + WF_PORT + "/workflows/wf/workflows"; + String expectedChangedUrl = WF_PROTOCOL + "://" + WF_HOST + ":" + WF_PORT + "/wf/workflows"; when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(requestResourceUrl)); when(servletRequest.getContextPath()).thenReturn("/sdc1"); @@ -195,14 +212,70 @@ public class FeProxyServletTest { assertEquals(expectedChangedUrl, rewriteURI); } - /** - * class for testing only exposes the protected method. - */ - public static class FeProxyServletForTest extends FeProxyServlet{ + @Test + public void testRedirectToMSWhenMsUrlExists() throws MalformedURLException { + final String urlParams = "x=1&y=2&z=3"; + final String url = "http//test.com:8080/uicache/v1/catalog"; + setUpConfigMocks(); + when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(url)); + when(servletRequest.getQueryString()).thenReturn(urlParams); + assertTrue(feProxy.isMsRequest(url + urlParams)); + assertEquals(msUrl + "/uicache/v1/catalog?" + urlParams, + feProxy.redirectMsRequestToMservice(servletRequest, configuration)); + } + + @Test + public void testRedirectToMSWhenMsUrlExistsWithoutParams() throws MalformedURLException { + final String uri = "/uicache/v1/home"; + final String url = String.format("http//test.com:8080%s", uri); + setUpConfigMocks(); + when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(url)); + when(servletRequest.getRequestURI()).thenReturn(uri); + assertTrue(feProxy.isMsRequest(url)); + assertEquals(msUrl + "/uicache/v1/home", feProxy.redirectMsRequestToMservice(servletRequest, configuration)); + } + @Test + public void testRedirectToBeOnToggleOff() throws MalformedURLException { + final String uri = "/uicache/v1/catalog"; + final String url = String.format("http//test.com:8080%s", uri); + when(catalogFacadeMsConfig.getPath()).thenReturn(null); + + when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(url)); + when(servletRequest.getRequestURI()).thenReturn(uri); + assertTrue(feProxy.isMsRequest(url)); + String expectedUrl = String.format("%s://%s:%s/rest/v1/screen?excludeTypes=VFCMT&excludeTypes=Configuration", + BE_PROTOCOL, BE_HOST, BE_PORT); + assertEquals(expectedUrl, feProxy.redirectMsRequestToMservice(servletRequest, configuration)); + } + @Test(expected = StringIndexOutOfBoundsException.class) + public void testRedirectToMSWhenMsUrlExistsButItIsNotCatalogRequest() throws MalformedURLException { + final String url = "http//test.com:8080/rest/v1/sc"; + final String urlParams = "x=1&y=2&z=3"; + setUpConfigMocks(); + when(servletRequest.getRequestURL()).thenReturn(new StringBuffer(url)); + when(servletRequest.getQueryString()).thenReturn(urlParams); + assertFalse(feProxy.isMsRequest(url)); + feProxy.redirectMsRequestToMservice(servletRequest, configuration); + } + private void setUpConfigMocks() { + when(catalogFacadeMsConfig.getPath()).thenReturn(msPath); + when(catalogFacadeMsConfig.getProtocol()).thenReturn(msProtocol); + when(catalogFacadeMsConfig.getHost()).thenReturn(msHost); + when(catalogFacadeMsConfig.getPort()).thenReturn(msPort); + when(catalogFacadeMsConfig.getHealthCheckUri()).thenReturn(msHealth); + } + + /* class for testing only exposes the protected method.*/ + public static class FeProxyServletForTest extends FeProxyServlet{ + private static final long serialVersionUID = 1L; @Override public String rewriteTarget(HttpServletRequest request) { return super.rewriteTarget(request); } + @Override + boolean isMsRequest(String currentUrl) { + return super.isMsRequest(currentUrl); + } } } diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/HealthCheckServiceTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/HealthCheckServiceTest.java deleted file mode 100644 index 31b3c90741..0000000000 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/HealthCheckServiceTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 Samsung. 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 static org.junit.Assert.assertEquals; - -import javax.servlet.ServletContext; -import javax.ws.rs.core.Response; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class HealthCheckServiceTest { - - - @Mock - private ServletContext context; - - private final HealthCheckService healthCheckService = new HealthCheckService(context); - private final Response response = Response.status(500).entity("{}").build(); - - - @Test - public void testGetFeHealth() { - //given - Response feHealth = healthCheckService.getFeHealth(); - - //then - assertEquals(response.getEntity(), feHealth.getEntity()); - assertEquals(response.getStatus(), feHealth.getStatus()); - } - - @Test - public void testGetLastHealthStatus() { - //given - HealthCheckService.HealthStatus healthStatus = healthCheckService.getLastHealthStatus(); - - //then - assertEquals(response.getEntity(), healthStatus.getBody()); - assertEquals(response.getStatus(), healthStatus.getStatusCode()); - } - - @Test - public void testGetTask () { - //given - HealthCheckService.HealthCheckScheduledTask healthCheckScheduledTask = healthCheckService.getTask(); - HealthCheckService.HealthStatus healthStatus = healthCheckScheduledTask.checkHealth(); - - //then - assertEquals(response.getStatus(),healthStatus.getStatusCode()); - } -} diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/KibanaServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/KibanaServletTest.java deleted file mode 100644 index f946891aa9..0000000000 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/KibanaServletTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 Samsung. 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 static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.fe.config.Configuration; -import org.openecomp.sdc.fe.config.ConfigurationManager; - -@RunWith(MockitoJUnitRunner.class) -public class KibanaServletTest { - - private static final int KIBANA_PORT = 9898; - private static final String CONTEXT_PATH = "/context"; - private static final String SERVLET_PATH = "/sdc1/kibanaProxy"; - private static final String PATH_INFO = "/info"; - private static final String QUERY_STRING = "query=projectR"; - private static final String REQUEST_URI = "uri"; - private static final String KIBANA_PROTOCOL = "kbn"; - private static final String KIBANA_HOST = "kibana.com"; - private static final String EXPECTED = "kbn://kibana.com:9898/context/info?query=projectR"; - - private final KibanaServlet kibanaServlet = new KibanaServlet(); - - @Mock - private Configuration configuration; - - @Mock - private ConfigurationManager manager; - - @Mock - private ServletContext context; - - @Mock - private HttpSession session; - - @Mock - private HttpServletRequest request; - - @Test - public void testRewriteTarget() { - // given - when(manager.getConfiguration()).thenReturn(configuration); - when(context.getAttribute(eq(Constants.CONFIGURATION_MANAGER_ATTR))).thenReturn(manager); - when(session.getServletContext()).thenReturn(context); - when(request.getSession()).thenReturn(session); - - when(request.getContextPath()).thenReturn(CONTEXT_PATH); - when(request.getServletPath()).thenReturn(SERVLET_PATH); - when(request.getPathInfo()).thenReturn(PATH_INFO); - when(request.getQueryString()).thenReturn(QUERY_STRING); - when(request.getRequestURI()).thenReturn(REQUEST_URI); - - when(configuration.getKibanaProtocol()).thenReturn(KIBANA_PROTOCOL); - when(configuration.getKibanaHost()).thenReturn(KIBANA_HOST); - when(configuration.getKibanaPort()).thenReturn(KIBANA_PORT); - - // when - final String url = kibanaServlet.rewriteTarget(request); - - // then - assertEquals(EXPECTED, url); - } -} diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PluginStatusBLTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PluginStatusBLTest.java index 8bf4e478b4..f435e2d80e 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PluginStatusBLTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PluginStatusBLTest.java @@ -41,90 +41,89 @@ import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; public class PluginStatusBLTest { - final static CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class); - PluginStatusBL pluginStatusBL = new PluginStatusBL(httpClient); - private static Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - final static ConfigurationManager configurationManager = Mockito.mock(ConfigurationManager.class); - final static PluginsConfiguration pluginsConfiguration = Mockito.mock(PluginsConfiguration.class); - final static Plugin offlinePlugin = new Plugin(); - final static Plugin onlinePlugin = new Plugin(); - final static CloseableHttpResponse httpResponse = Mockito.mock(CloseableHttpResponse.class); - final static StatusLine statusLine = Mockito.mock(StatusLine.class); - static List<Plugin> testPluginsList = new ArrayList<>(); - static List<Plugin> assertPluginList = new ArrayList<>(); - - final static String offlinePluginsDisplayName = "offlinePlugin"; - final static String offlinePluginDiscoveryPath = "http://192.168.10.1:1000/offline"; - - final static String onlinePluginDisplayName = "onlinePlugin"; - final static String onlinePluginDiscoveryPath = "http://192.168.10.1:2000/online"; - - @BeforeClass - public static void beforeClass() { - ConfigurationManager.setTestInstance(configurationManager); - when(configurationManager.getPluginsConfiguration()).thenReturn(pluginsConfiguration); - - offlinePlugin.setPluginId(offlinePluginsDisplayName); - offlinePlugin.setPluginDiscoveryUrl(offlinePluginDiscoveryPath); - - onlinePlugin.setPluginId(onlinePluginDisplayName); - onlinePlugin.setPluginDiscoveryUrl(onlinePluginDiscoveryPath); - } - - @Before - public void beforeTest() { - testPluginsList = new ArrayList<>(); - assertPluginList = new ArrayList<>(); - } - - @Test - public void TestPluginsConfigurationListReturnsWithWantedPlugins() { - testPluginsList.add(offlinePlugin); - testPluginsList.add(onlinePlugin); - when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); - - assertPluginList.add(offlinePlugin); - assertPluginList.add(onlinePlugin); - - String result = gson.toJson(assertPluginList); - String actualResult = pluginStatusBL.getPluginsList(); - - assertEquals(actualResult, result); - } - - @Test - public void TestGetPluginAvailabilityShouldReturnFalseWhenPluginIsOffline() throws ClientProtocolException, IOException { - testPluginsList.add(offlinePlugin); - when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); - - when(statusLine.getStatusCode()).thenReturn(404); - when(httpResponse.getStatusLine()).thenReturn(statusLine); - when(httpClient.execute(Mockito.any(HttpHead.class))).thenReturn(httpResponse); - - String result = gson.toJson(false); - String actualResult = pluginStatusBL.getPluginAvailability(offlinePlugin.getPluginId()); - - assertEquals(actualResult, result); - } - - @Test - public void TestOnlinePluginBeingReturnedWithIsOnlineValueTrue() throws ClientProtocolException, IOException { - testPluginsList.add(onlinePlugin); - when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); - - when(statusLine.getStatusCode()).thenReturn(200); - when(httpResponse.getStatusLine()).thenReturn(statusLine); - when(httpClient.execute(Mockito.any())).thenReturn(httpResponse); - - String result = gson.toJson(true); - String actualResult = pluginStatusBL.getPluginAvailability(onlinePlugin.getPluginId()); - - assertEquals(actualResult, result); - } + final static CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class); + PluginStatusBL pluginStatusBL = new PluginStatusBL(httpClient); + private static Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + final static ConfigurationManager configurationManager = Mockito.mock(ConfigurationManager.class); + final static PluginsConfiguration pluginsConfiguration = Mockito.mock(PluginsConfiguration.class); + final static Plugin offlinePlugin = new Plugin(); + final static Plugin onlinePlugin = new Plugin(); + final static CloseableHttpResponse httpResponse = Mockito.mock(CloseableHttpResponse.class); + final static StatusLine statusLine = Mockito.mock(StatusLine.class); + static List<Plugin> testPluginsList = new ArrayList<>(); + static List<Plugin> assertPluginList = new ArrayList<>(); + + final static String offlinePluginsDisplayName = "offlinePlugin"; + final static String offlinePluginDiscoveryPath = "http://192.168.10.1:1000/offline"; + + final static String onlinePluginDisplayName = "onlinePlugin"; + final static String onlinePluginDiscoveryPath = "http://192.168.10.1:2000/online"; + + @BeforeClass + public static void beforeClass() { + ConfigurationManager.setTestInstance(configurationManager); + when(configurationManager.getPluginsConfiguration()).thenReturn(pluginsConfiguration); + + offlinePlugin.setPluginId(offlinePluginsDisplayName); + offlinePlugin.setPluginDiscoveryUrl(offlinePluginDiscoveryPath); + + onlinePlugin.setPluginId(onlinePluginDisplayName); + onlinePlugin.setPluginDiscoveryUrl(onlinePluginDiscoveryPath); + } + + @Before + public void beforeTest() { + testPluginsList = new ArrayList<>(); + assertPluginList = new ArrayList<>(); + } + + @Test + public void TestPluginsConfigurationListReturnsWithWantedPlugins() { + testPluginsList.add(offlinePlugin); + testPluginsList.add(onlinePlugin); + when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); + + assertPluginList.add(offlinePlugin); + assertPluginList.add(onlinePlugin); + + String result = gson.toJson(assertPluginList); + String actualResult = pluginStatusBL.getPluginsList(); + + assertEquals(actualResult, result); + } + + @Test + public void TestGetPluginAvailabilityShouldReturnFalseWhenPluginIsOffline() throws ClientProtocolException, IOException { + testPluginsList.add(offlinePlugin); + when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); + + when(statusLine.getStatusCode()).thenReturn(404); + when(httpResponse.getStatusLine()).thenReturn(statusLine); + when(httpClient.execute(Mockito.any(HttpHead.class))).thenReturn(httpResponse); + + String result = gson.toJson(false); + String actualResult = pluginStatusBL.getPluginAvailability(offlinePlugin.getPluginId()); + + assertEquals(actualResult, result); + } + + @Test + public void TestOnlinePluginBeingReturnedWithIsOnlineValueTrue() throws ClientProtocolException, IOException { + testPluginsList.add(onlinePlugin); + when(pluginsConfiguration.getPluginsList()).thenReturn(testPluginsList); + + when(statusLine.getStatusCode()).thenReturn(200); + when(httpResponse.getStatusLine()).thenReturn(statusLine); + when(httpClient.execute(Mockito.any())).thenReturn(httpResponse); + + String result = gson.toJson(true); + String actualResult = pluginStatusBL.getPluginAvailability(onlinePlugin.getPluginId()); + + assertEquals(actualResult, result); + } } diff --git a/catalog-fe/src/test/java/org/openecomp/sdc/servlets/PortalServletTest.java b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PortalServletTest.java index 72d279d3e5..fccb41bc99 100644 --- a/catalog-fe/src/test/java/org/openecomp/sdc/servlets/PortalServletTest.java +++ b/catalog-fe/src/test/java/org/openecomp/sdc/fe/servlets/PortalServletTest.java @@ -18,21 +18,27 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.sdc.servlets; +package org.openecomp.sdc.fe.servlets; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; +import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import org.onap.sdc.security.CipherUtil; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.fe.config.Configuration; import org.openecomp.sdc.fe.config.ConfigurationManager; -import org.openecomp.sdc.fe.servlets.PortalServlet; -import javax.servlet.*; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +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 javax.servlet.http.HttpSession; @@ -42,7 +48,12 @@ import java.util.ArrayList; import java.util.List; import static org.glassfish.jersey.test.TestProperties.CONTAINER_PORT; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + public class PortalServletTest extends JerseyTest { @@ -53,6 +64,8 @@ public class PortalServletTest extends JerseyTest { private final static Configuration configuration = Mockito.mock(Configuration.class); private final static HttpServletResponse response = Mockito.spy(HttpServletResponse.class); private final static RequestDispatcher rd = Mockito.spy(RequestDispatcher.class); + private static CipherUtil cipherUtil = Mockito.mock(CipherUtil.class); + final static Configuration.CookieConfig cookieConfiguration = Mockito.mock(Configuration.CookieConfig.class); @SuppressWarnings("serial") @BeforeClass @@ -62,6 +75,7 @@ public class PortalServletTest extends JerseyTest { when(httpSession.getServletContext()).thenReturn(servletContext); when(servletContext.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).thenReturn(configurationManager); when(configurationManager.getConfiguration()).thenReturn(configuration); + when(configuration.getAuthCookie()).thenReturn(cookieConfiguration); List<List<String>> mandatoryHeaders = new ArrayList<>(); mandatoryHeaders.add(new ArrayList<String>() { { @@ -113,25 +127,58 @@ public class PortalServletTest extends JerseyTest { } + @After + public void tearDown() { + Mockito.reset(response, rd); + } + @Test public void testMissingHeadersRequest() throws IOException { when(request.getHeader(Mockito.anyString())).thenReturn(null); - target().path("/portal").request().get(); + when(request.getCookies()).thenReturn(getCookies()); + target().path("/portal").request().get(); Mockito.verify(response, times(1)).sendError(HttpServletResponse.SC_USE_PROXY, PortalServlet.MISSING_HEADERS_MSG); - Mockito.reset(response, rd); } @Test public void testSuccessfulRequest() throws IOException, ServletException { - Mockito.doAnswer((Answer<Object>) invocation -> { + ConfigurationManager.setTestInstance(configurationManager); + when(configuration.getAuthCookie().getCookieName()).thenReturn("cookieName"); + when(configuration.getAuthCookie().getPath()).thenReturn("/"); + when(configuration.getAuthCookie().getDomain()).thenReturn(""); + when(configuration.getAuthCookie().getSecurityKey()).thenReturn(""); + Mockito.doAnswer((Answer<Object>) invocation -> { Object[] args = invocation.getArguments(); return (String) args[0]; }).when(request).getHeader(Mockito.anyString()); target().path("/portal").request().get(); verify(rd).forward(Mockito.any(ServletRequest.class), Mockito.any(ServletResponse.class)); - Mockito.reset(response, rd); } + + @Test + public void testSuccessfullAddofAuthCookie() throws IOException, ServletException { + ConfigurationManager.setTestInstance(configurationManager); + when(configuration.getAuthCookie().getCookieName()).thenReturn("cookieName"); + when(configuration.getAuthCookie().getPath()).thenReturn("/"); + when(configuration.getAuthCookie().getDomain()).thenReturn(""); + when(configuration.getAuthCookie().getSecurityKey()).thenReturn("AGLDdG4D04BKm2IxIWEr8o=="); + PortalServlet pp = new PortalServlet(); + assertTrue(pp.addAuthCookie(response,"user", "test" ,"User")); + } + + @Test + public void testFailureMissingCookieConfiguration() throws IOException { + + //missing configuration mock therefore will fail + PortalServlet pp = new PortalServlet(); + pp.doGet(request,response); + assertFalse(pp.addAuthCookie(response,"user", "test" ,"User")); + + } + + + @Override protected Application configure() { // Use any available port - this allows us to run the BE tests in parallel with this one. @@ -146,6 +193,15 @@ public class PortalServletTest extends JerseyTest { } }); + + return resourceConfig; } + + private Cookie[] getCookies() { + Cookie[] cookies = new Cookie [1]; + cookies[0] = new Cookie("someName", "aaa"); + return cookies; + } + } diff --git a/catalog-fe/src/test/resources/config/ESAPI.properties b/catalog-fe/src/test/resources/config/ESAPI.properties new file mode 100644 index 0000000000..1dedfe6739 --- /dev/null +++ b/catalog-fe/src/test/resources/config/ESAPI.properties @@ -0,0 +1,452 @@ +# +# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version +# +# This file is part of the Open Web Application Security Project (OWASP) +# Enterprise Security API (ESAPI) project. For details, please see +# http://www.owasp.org/index.php/ESAPI. +# +# Copyright (c) 2008,2009 - The OWASP Foundation +# +# DISCUSS: This may cause a major backwards compatibility issue, etc. but +# from a name space perspective, we probably should have prefaced +# all the property names with ESAPI or at least OWASP. Otherwise +# there could be problems is someone loads this properties file into +# the System properties. We could also put this file into the +# esapi.jar file (perhaps as a ResourceBundle) and then allow an external +# ESAPI properties be defined that would overwrite these defaults. +# That keeps the application's properties relatively simple as usually +# they will only want to override a few properties. If looks like we +# already support multiple override levels of this in the +# DefaultSecurityConfiguration class, but I'm suggesting placing the +# defaults in the esapi.jar itself. That way, if the jar is signed, +# we could detect if those properties had been tampered with. (The +# code to check the jar signatures is pretty simple... maybe 70-90 LOC, +# but off course there is an execution penalty (similar to the way +# that the separate sunjce.jar used to be when a class from it was +# first loaded). Thoughts? +############################################################################### +# +# WARNING: Operating system protection should be used to lock down the .esapi +# resources directory and all the files inside and all the directories all the +# way up to the root directory of the file system. Note that if you are using +# file-based implementations, that some files may need to be read-write as they +# get updated dynamically. +# +# Before using, be sure to update the MasterKey and MasterSalt as described below. +# N.B.: If you had stored data that you have previously encrypted with ESAPI 1.4, +# you *must* FIRST decrypt it using ESAPI 1.4 and then (if so desired) +# re-encrypt it with ESAPI 2.0. If you fail to do this, you will NOT be +# able to decrypt your data with ESAPI 2.0. +# +# YOU HAVE BEEN WARNED!!! More details are in the ESAPI 2.0 Release Notes. +# +#=========================================================================== +# ESAPI Configuration +# +# If true, then print all the ESAPI properties set here when they are loaded. +# If false, they are not printed. Useful to reduce output when running JUnit tests. +# If you need to troubleshoot a properties related problem, turning this on may help. +# This is 'false' in the src/test/resources/.esapi version. It is 'true' by +# default for reasons of backward compatibility with earlier ESAPI versions. +ESAPI.printProperties=true + +# ESAPI is designed to be easily extensible. You can use the reference implementation +# or implement your own providers to take advantage of your enterprise's security +# infrastructure. The functions in ESAPI are referenced using the ESAPI locator, like: +# +# String ciphertext = +# ESAPI.encryptor().encrypt("Secret message"); // Deprecated in 2.0 +# CipherText cipherText = +# ESAPI.encryptor().encrypt(new PlainText("Secret message")); // Preferred +# +# Below you can specify the classname for the provider that you wish to use in your +# application. The only requirement is that it implement the appropriate ESAPI interface. +# This allows you to switch security implementations in the future without rewriting the +# entire application. +# +# ExperimentalAccessController requires ESAPI-AccessControlPolicy.xml in .esapi directory +ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController +# FileBasedAuthenticator requires users.txt file in .esapi directory +ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator +ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder +ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor + +ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor +ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities +ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector +# Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html +ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory +#ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory +ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer +ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator + +#=========================================================================== +# ESAPI Authenticator +# +Authenticator.AllowedLoginAttempts=3 +Authenticator.MaxOldPasswordHashes=13 +Authenticator.UsernameParameterName=username +Authenticator.PasswordParameterName=password +# RememberTokenDuration (in days) +Authenticator.RememberTokenDuration=14 +# Session Timeouts (in minutes) +Authenticator.IdleTimeoutDuration=20 +Authenticator.AbsoluteTimeoutDuration=120 + +#=========================================================================== +# ESAPI Encoder +# +# ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks. +# Failure to canonicalize input is a very common mistake when implementing validation schemes. +# Canonicalization is automatic when using the ESAPI Validator, but you can also use the +# following code to canonicalize data. +# +# ESAPI.Encoder().canonicalize( "%22hello world"" ); +# +# Multiple encoding is when a single encoding format is applied multiple times. Allowing +# multiple encoding is strongly discouraged. +Encoder.AllowMultipleEncoding=false + +# Mixed encoding is when multiple different encoding formats are applied, or when +# multiple formats are nested. Allowing multiple encoding is strongly discouraged. +Encoder.AllowMixedEncoding=false + +# The default list of codecs to apply when canonicalizing untrusted data. The list should include the codecs +# for all downstream interpreters or decoders. For example, if the data is likely to end up in a URL, HTML, or +# inside JavaScript, then the list of codecs below is appropriate. The order of the list is not terribly important. +Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec + + +#=========================================================================== +# ESAPI Encryption +# +# The ESAPI Encryptor provides basic cryptographic functions with a simplified API. +# To get started, generate a new key using java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# There is not currently any support for key rotation, so be careful when changing your key and salt as it +# will invalidate all signed, encrypted, and hashed data. +# +# WARNING: Not all combinations of algorithms and key lengths are supported. +# If you choose to use a key length greater than 128, you MUST download the +# unlimited strength policy files and install in the lib directory of your JRE/JDK. +# See http://java.sun.com/javase/downloads/index.jsp for more information. +# +# Backward compatibility with ESAPI Java 1.4 is supported by the two deprecated API +# methods, Encryptor.encrypt(String) and Encryptor.decrypt(String). However, whenever +# possible, these methods should be avoided as they use ECB cipher mode, which in almost +# all circumstances a poor choice because of it's weakness. CBC cipher mode is the default +# for the new Encryptor encrypt / decrypt methods for ESAPI Java 2.0. In general, you +# should only use this compatibility setting if you have persistent data encrypted with +# version 1.4 and even then, you should ONLY set this compatibility mode UNTIL +# you have decrypted all of your old encrypted data and then re-encrypted it with +# ESAPI 2.0 using CBC mode. If you have some reason to mix the deprecated 1.4 mode +# with the new 2.0 methods, make sure that you use the same cipher algorithm for both +# (256-bit AES was the default for 1.4; 128-bit is the default for 2.0; see below for +# more details.) Otherwise, you will have to use the new 2.0 encrypt / decrypt methods +# where you can specify a SecretKey. (Note that if you are using the 256-bit AES, +# that requires downloading the special jurisdiction policy files mentioned above.) +# +# ***** IMPORTANT: Do NOT forget to replace these with your own values! ***** +# To calculate these values, you can run: +# java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# +Encryptor.MasterKey=tzfztf56ftv +Encryptor.MasterSalt=123456ztrewq + +# Provides the default JCE provider that ESAPI will "prefer" for its symmetric +# encryption and hashing. (That is it will look to this provider first, but it +# will defer to other providers if the requested algorithm is not implemented +# by this provider.) If left unset, ESAPI will just use your Java VM's current +# preferred JCE provider, which is generally set in the file +# "$JAVA_HOME/jre/lib/security/java.security". +# +# The main intent of this is to allow ESAPI symmetric encryption to be +# used with a FIPS 140-2 compliant crypto-module. For details, see the section +# "Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules" in +# the ESAPI 2.0 Symmetric Encryption User Guide, at: +# http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html +# However, this property also allows you to easily use an alternate JCE provider +# such as "Bouncy Castle" without having to make changes to "java.security". +# See Javadoc for SecurityProviderLoader for further details. If you wish to use +# a provider that is not known to SecurityProviderLoader, you may specify the +# fully-qualified class name of the JCE provider class that implements +# java.security.Provider. If the name contains a '.', this is interpreted as +# a fully-qualified class name that implements java.security.Provider. +# +# NOTE: Setting this property has the side-effect of changing it in your application +# as well, so if you are using JCE in your application directly rather than +# through ESAPI (you wouldn't do that, would you? ;-), it will change the +# preferred JCE provider there as well. +# +# Default: Keeps the JCE provider set to whatever JVM sets it to. +Encryptor.PreferredJCEProvider= + +# AES is the most widely used and strongest encryption algorithm. This +# should agree with your Encryptor.CipherTransformation property. +# By default, ESAPI Java 1.4 uses "PBEWithMD5AndDES" and which is +# very weak. It is essentially a password-based encryption key, hashed +# with MD5 around 1K times and then encrypted with the weak DES algorithm +# (56-bits) using ECB mode and an unspecified padding (it is +# JCE provider specific, but most likely "NoPadding"). However, 2.0 uses +# "AES/CBC/PKCSPadding". If you want to change these, change them here. +# Warning: This property does not control the default reference implementation for +# ESAPI 2.0 using JavaEncryptor. Also, this property will be dropped +# in the future. +# @deprecated +Encryptor.EncryptionAlgorithm=AES +# For ESAPI Java 2.0 - New encrypt / decrypt methods use this. +Encryptor.CipherTransformation=AES/CBC/PKCS5Padding + +# Applies to ESAPI 2.0 and later only! +# Comma-separated list of cipher modes that provide *BOTH* +# confidentiality *AND* message authenticity. (NIST refers to such cipher +# modes as "combined modes" so that's what we shall call them.) If any of these +# cipher modes are used then no MAC is calculated and stored +# in the CipherText upon encryption. Likewise, if one of these +# cipher modes is used with decryption, no attempt will be made +# to validate the MAC contained in the CipherText object regardless +# of whether it contains one or not. Since the expectation is that +# these cipher modes support support message authenticity already, +# injecting a MAC in the CipherText object would be at best redundant. +# +# Note that as of JDK 1.5, the SunJCE provider does not support *any* +# of these cipher modes. Of these listed, only GCM and CCM are currently +# NIST approved. YMMV for other JCE providers. E.g., Bouncy Castle supports +# GCM and CCM with "NoPadding" mode, but not with "PKCS5Padding" or other +# padding modes. +Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC + +# Applies to ESAPI 2.0 and later only! +# Additional cipher modes allowed for ESAPI 2.0 encryption. These +# cipher modes are in _addition_ to those specified by the property +# 'Encryptor.cipher_modes.combined_modes'. +# Note: We will add support for streaming modes like CFB & OFB once +# we add support for 'specified' to the property 'Encryptor.ChooseIVMethod' +# (probably in ESAPI 2.1). +# DISCUSS: Better name? +Encryptor.cipher_modes.additional_allowed=CBC + +# 128-bit is almost always sufficient and appears to be more resistant to +# related key attacks than is 256-bit AES. Use '_' to use default key size +# for cipher algorithms (where it makes sense because the algorithm supports +# a variable key size). Key length must agree to what's provided as the +# cipher transformation, otherwise this will be ignored after logging a +# warning. +# +# NOTE: This is what applies BOTH ESAPI 1.4 and 2.0. See warning above about mixing! +Encryptor.EncryptionKeyLength=128 + +# Because 2.0 uses CBC mode by default, it requires an initialization vector (IV). +# (All cipher modes except ECB require an IV.) There are two choices: we can either +# use a fixed IV known to both parties or allow ESAPI to choose a random IV. While +# the IV does not need to be hidden from adversaries, it is important that the +# adversary not be allowed to choose it. Also, random IVs are generally much more +# secure than fixed IVs. (In fact, it is essential that feed-back cipher modes +# such as CFB and OFB use a different IV for each encryption with a given key so +# in such cases, random IVs are much preferred. By default, ESAPI 2.0 uses random +# IVs. If you wish to use 'fixed' IVs, set 'Encryptor.ChooseIVMethod=fixed' and +# uncomment the Encryptor.fixedIV. +# +# Valid values: random|fixed|specified 'specified' not yet implemented; planned for 2.1 +Encryptor.ChooseIVMethod=random +# If you choose to use a fixed IV, then you must place a fixed IV here that +# is known to all others who are sharing your secret key. The format should +# be a hex string that is the same length as the cipher block size for the +# cipher algorithm that you are using. The following is an *example* for AES +# from an AES test vector for AES-128/CBC as described in: +# NIST Special Publication 800-38A (2001 Edition) +# "Recommendation for Block Cipher Modes of Operation". +# (Note that the block size for AES is 16 bytes == 128 bits.) +# +Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f + +# Whether or not CipherText should use a message authentication code (MAC) with it. +# This prevents an adversary from altering the IV as well as allowing a more +# fool-proof way of determining the decryption failed because of an incorrect +# key being supplied. This refers to the "separate" MAC calculated and stored +# in CipherText, not part of any MAC that is calculated as a result of a +# "combined mode" cipher mode. +# +# If you are using ESAPI with a FIPS 140-2 cryptographic module, you *must* also +# set this property to false. +Encryptor.CipherText.useMAC=true + +# Whether or not the PlainText object may be overwritten and then marked +# eligible for garbage collection. If not set, this is still treated as 'true'. +Encryptor.PlainText.overwrite=true + +# Do not use DES except in a legacy situations. 56-bit is way too small key size. +#Encryptor.EncryptionKeyLength=56 +#Encryptor.EncryptionAlgorithm=DES + +# TripleDES is considered strong enough for most purposes. +# Note: There is also a 112-bit version of DESede. Using the 168-bit version +# requires downloading the special jurisdiction policy from Sun. +#Encryptor.EncryptionKeyLength=168 +#Encryptor.EncryptionAlgorithm=DESede + +Encryptor.HashAlgorithm=SHA-512 +Encryptor.HashIterations=1024 +Encryptor.DigitalSignatureAlgorithm=SHA1withDSA +Encryptor.DigitalSignatureKeyLength=1024 +Encryptor.RandomAlgorithm=SHA1PRNG +Encryptor.CharacterEncoding=UTF-8 + +# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function +# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and +# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for +# the MAC, mostly to keep the overall size at a minimum.) +# +# Currently supported choices for JDK 1.5 and 1.6 are: +# HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and +# HmacSHA512 (512 bits). +# Note that HmacMD5 is *not* supported for the PRF used by the KDF even though +# the JDKs support it. See the ESAPI 2.0 Symmetric Encryption User Guide +# further details. +Encryptor.KDF.PRF=HmacSHA256 +#=========================================================================== +# ESAPI HttpUtilties +# +# The HttpUtilities provide basic protections to HTTP requests and responses. Primarily these methods +# protect against malicious data from attackers, such as unprintable characters, escaped characters, +# and other simple attacks. The HttpUtilities also provides utility methods for dealing with cookies, +# headers, and CSRF tokens. +# +# Default file upload location (remember to escape backslashes with \\) +HttpUtilities.UploadDir=C:\\ESAPI\\testUpload +HttpUtilities.UploadTempDir=C:\\temp +# Force flags on cookies, if you use HttpUtilities to set cookies +HttpUtilities.ForceHttpOnlySession=false +HttpUtilities.ForceSecureSession=false +HttpUtilities.ForceHttpOnlyCookies=true +HttpUtilities.ForceSecureCookies=true +# Maximum size of HTTP headers +HttpUtilities.MaxHeaderSize=4096 +# File upload configuration +HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll +HttpUtilities.MaxUploadFileBytes=500000000 +# Using UTF-8 throughout your stack is highly recommended. That includes your database driver, +# container, and any other technologies you may be using. Failure to do this may expose you +# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization. +HttpUtilities.ResponseContentType=text/html; charset=UTF-8 +# This is the name of the cookie used to represent the HTTP session +# Typically this will be the default "JSESSIONID" +HttpUtilities.HttpSessionIdName=JSESSIONID + + + +#=========================================================================== +# ESAPI Executor +# CHECKME - Not sure what this is used for, but surely it should be made OS independent. +Executor.WorkingDirectory=C:\\Windows\\Temp +Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe + + +#=========================================================================== +# ESAPI Logging +# Set the application name if these logs are combined with other applications +Logger.ApplicationName=ExampleApplication +# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true +Logger.LogEncodingRequired=false +# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments. +Logger.LogApplicationName=true +# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments. +Logger.LogServerIP=true +# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you +# want to place it in a specific directory. +Logger.LogFileName=ESAPI_logging_file +# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000) +Logger.MaxLogFileSize=10000000 + + +#=========================================================================== +# ESAPI Intrusion Detection +# +# Each event has a base to which .count, .interval, and .action are added +# The IntrusionException will fire if we receive "count" events within "interval" seconds +# The IntrusionDetector is configurable to take the following actions: log, logout, and disable +# (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable +# +# Custom Events +# Names must start with "event." as the base +# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here +# You can also disable intrusion detection completely by changing +# the following parameter to true +# +IntrusionDetector.Disable=false +# +IntrusionDetector.event.test.count=2 +IntrusionDetector.event.test.interval=10 +IntrusionDetector.event.test.actions=disable,log + +# Exception Events +# All EnterpriseSecurityExceptions are registered automatically +# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException +# Use the fully qualified classname of the exception as the base + +# any intrusion is an attack +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout + +# for test purposes +# CHECKME: Shouldn't there be something in the property name itself that designates +# that these are for testing??? +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout + +# rapid validation errors indicate scans or attacks in progress +# org.owasp.esapi.errors.ValidationException.count=10 +# org.owasp.esapi.errors.ValidationException.interval=10 +# org.owasp.esapi.errors.ValidationException.actions=log,logout + +# sessions jumping between hosts indicates session hijacking +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout + + +#=========================================================================== +# ESAPI Validation +# +# The ESAPI Validator works on regular expressions with defined names. You can define names +# either here, or you may define application specific patterns in a separate file defined below. +# This allows enterprises to specify both organizational standards as well as application specific +# validation rules. +# +Validator.ConfigurationFile=validation.properties + +# Validators used by ESAPI +Validator.AccountName=^[a-zA-Z0-9]{3,20}$ +Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$ +Validator.RoleName=^[a-z]{1,20}$ + +#the word TEST below should be changed to your application +#name - only relative URL's are supported +Validator.Redirect=^\\/test.*$ + +# Global HTTP Validation Rules +# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=] +Validator.HTTPScheme=^(http|https)$ +Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$ +Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$ +Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$ +Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$ +Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$ +Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,32}$ +Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$ +Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$ +Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$ +Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$ +Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPURL=^.*$ +Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$ + +# Validation of file related input +Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ +Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ + +# Validation of dates. Controls whether or not 'lenient' dates are accepted. +# See DataFormat.setLenient(boolean flag) for further details. +Validator.AcceptLenientDates=false
\ No newline at end of file diff --git a/catalog-fe/src/test/resources/logback-test.xml b/catalog-fe/src/test/resources/logback-test.xml index d2b9bff23f..548a804952 100644 --- a/catalog-fe/src/test/resources/logback-test.xml +++ b/catalog-fe/src/test/resources/logback-test.xml @@ -3,7 +3,7 @@ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <Pattern> - %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n +<!-- %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n--> </Pattern> </encoder> </appender> |