All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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