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

com.sap.cloud.sdk.cloudplatform.concurrency.ScpNeoTenantCallable Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
 */

package com.sap.cloud.sdk.cloudplatform.concurrency;

import java.util.concurrent.Callable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.slf4j.Logger;

import com.sap.cloud.account.TenantAlreadySetException;
import com.sap.cloud.sdk.cloudplatform.exception.ShouldNotHappenException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.tenant.ScpNeoTenant;
import com.sap.cloud.sdk.cloudplatform.tenant.Tenant;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantAccessException;
import com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantNotAvailableException;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

/**
 * Wraps the given {@link Callable} to be executed in the context of the given tenant.
 */
@SuppressWarnings( "PMD.SignatureDeclareThrowsException" )
@RequiredArgsConstructor
@Getter
@ToString
public class ScpNeoTenantCallable implements Callable
{
    private static final Logger logger = CloudLoggerFactory.getLogger(ScpNeoTenantCallable.class);

    @Nonnull
    private final ScpNeoTenant tenant;

    @Nonnull
    private final Callable callable;

    private ScpNeoTenant getCurrentTenant()
        throws TenantNotAvailableException,
            TenantAccessException
    {
        final Tenant tenant = TenantAccessor.getCurrentTenant();

        if( !(tenant instanceof ScpNeoTenant) ) {
            throw new ShouldNotHappenException(
                "The current "
                    + Tenant.class.getSimpleName()
                    + " is not an instance of "
                    + ScpNeoTenant.class.getSimpleName()
                    + ". Please make sure to specify a dependency to com.sap.cloud.s4hana.cloudplatform:tenant-scp-neo.");
        }

        return (ScpNeoTenant) tenant;
    }

    @Nullable
    @Override
    public T call()
        throws Exception
    {
        if( logger.isDebugEnabled() ) {
            logger.debug(
                "Executing tenant callable in context of thread "
                    + Thread.currentThread().getId()
                    + " and tenant "
                    + tenant
                    + ".");
        }

        ScpNeoTenant tenantOfCurrentThread;

        try {
            tenantOfCurrentThread = getCurrentTenant();
        }
        catch( final TenantNotAvailableException | TenantAccessException e ) {
            if( logger.isDebugEnabled() ) {
                logger.debug("No tenant available. Using context of original tenant.", e);
            }
            tenantOfCurrentThread = tenant;
        }

        if( logger.isDebugEnabled() ) {
            logger.debug(
                "Executing callable in context of tenant "
                    + tenant
                    + " with the current thread running in the context of tenant "
                    + tenantOfCurrentThread
                    + ".");
        }

        try {
            return tenantOfCurrentThread.getTenantContext().execute(tenant.getTenantId(), callable);
        }
        catch( final TenantAlreadySetException e ) {

            // Originally, calling the execute() method on a TenantContext while providing the tenant identifier
            // of the TenantContext itself would throw a TenantAlreadySetException.
            //
            // While this should no longer happen [1], we keep the following direct invocation of the callable
            // to follow the official API documentation in case this behavior changes again.
            //
            // [1] https://git.wdf.sap.corp/#/q/Ib3952380e865de2683508247a087ae88ddc353b3

            return callable.call();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy