
com.sap.cloud.sdk.cloudplatform.tenant.AbstractTenantFacade Maven / Gradle / Ivy
/*
* Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.cloudplatform.tenant;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.servlet.Property;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContext;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextAccessor;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextExecutor;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextServletFilter;
import com.sap.cloud.sdk.cloudplatform.servlet.exception.RequestContextPropertyException;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantAccessException;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantNotAvailableException;
import io.vavr.control.Try;
/**
* Abstract base class for {@link TenantFacade}s which allows to use a mocked {@link Tenant} if the environment variable
* "USE_MOCKED_TENANT" is set to "true".
*/
public abstract class AbstractTenantFacade implements TenantFacade
{
private static final Logger logger = CloudLoggerFactory.getLogger(AbstractTenantFacade.class);
private static final String VARIABLE_USE_MOCKED_TENANT = "USE_MOCKED_TENANT";
/**
* Instantiates a mocked {@link Tenant}.
*
* @return A new mocked {@link Tenant}.
*/
@Nonnull
protected abstract Tenant newMockedTenant();
/**
* Returns a mocked {@link Tenant}, if the environment variable "USE_MOCKED_TENANT" is set to "true".
*
* @return The mocked {@link Tenant}, if present.
*/
@Nonnull
public Optional getMockedTenant()
{
@Nullable
final String env = System.getenv(VARIABLE_USE_MOCKED_TENANT);
if( Boolean.valueOf(env) ) {
logger.error(
"Using a mocked tenant with blank tenant identifier "
+ "since environment variable '"
+ VARIABLE_USE_MOCKED_TENANT
+ "' is set to 'true'. "
+ "SECURITY WARNING: This variable must never be used in productive environments!");
return Optional.of(newMockedTenant());
}
return Optional.empty();
}
/**
* {@inheritDoc}
*/
@Nonnull
@Override
public Tenant getCurrentTenant()
throws TenantNotAvailableException,
TenantAccessException
{
final Optional currentTenant = getCurrentTenantIfAvailable();
if( !currentTenant.isPresent() ) {
throw new TenantNotAvailableException(
"Failed to get current tenant: tenant not available. "
+ "For details on the security configuration, "
+ "please refer to the SAP Cloud Platform documentation. "
+ "Tutorials on the configuration are available at "
+ "'https://help.sap.com/viewer/p/SAP_CLOUD_SDK'.");
}
return currentTenant.get();
}
/**
* {@inheritDoc}
*/
@Nonnull
@Override
public Optional getCurrentTenantIfAvailable()
throws TenantAccessException
{
final Optional requestContext = RequestContextAccessor.getCurrentRequestContext();
if( !requestContext.isPresent() ) {
throw new TenantAccessException(
"Failed to get current tenant: no "
+ RequestContext.class.getSimpleName()
+ " available."
+ " Have you correctly configured a "
+ RequestContextServletFilter.class.getSimpleName()
+ " or have you wrapped your logic in a "
+ RequestContextExecutor.class.getSimpleName()
+ " when executing background tasks that are not triggered by a request?");
}
final Optional> property;
try {
property = requestContext.get().getProperty(TenantRequestContextListener.PROPERTY_TENANT);
}
catch( final RequestContextPropertyException e ) {
throw new TenantAccessException(
"Failed to get current tenant: failed to get " + RequestContext.class.getSimpleName() + " property.",
e);
}
if( !property.isPresent() ) {
throw new TenantAccessException(
"Failed to get current tenant: "
+ RequestContext.class.getSimpleName()
+ " property '"
+ TenantRequestContextListener.PROPERTY_TENANT
+ "' not initialized."
+ " Have you correctly configured a "
+ TenantRequestContextListener.class.getSimpleName()
+ " in the relevant "
+ RequestContextServletFilter.class.getSimpleName()
+ " or "
+ RequestContextExecutor.class.getSimpleName()
+ "?");
}
@Nullable
final Exception exception = property.get().getException();
if( exception != null ) {
throw new TenantAccessException("Failed to get current tenant.", exception);
}
@Nullable
final Tenant tenant = (Tenant) property.get().getValue();
return Optional.ofNullable(tenant);
}
/**
* {@inheritDoc}
*/
@Nonnull
@Override
public Try tryGetCurrentTenant()
{
return Try.of(this::getCurrentTenant);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy