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

com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand Maven / Gradle / Ivy

Go to download

Implementation of the Cloud platform abstraction for general-purpose connectivity on the SAP Cloud Platform (Cloud Foundry).

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

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

import javax.annotation.Nonnull;

import org.slf4j.Logger;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestDeniedException;
import com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException;
import com.sap.cloud.sdk.cloudplatform.tenant.Tenant;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor;
import com.sap.cloud.sdk.frameworks.hystrix.Command;
import com.sap.cloud.sdk.frameworks.hystrix.HystrixUtil;

import lombok.Data;

class DestinationServiceCommand extends Command
{
    private static final Logger logger = CloudLoggerFactory.getLogger(DestinationServiceCommand.class);

    @Data
    private static class CommandSetterBuilder
    {
        private final Class> commandClass;

        private String getCommandKey()
        {
            // TODO test isolation
            final String commandKey =
                HystrixUtil.getCommandKey(
                    commandClass,
                    TenantAccessor.getCurrentTenantIfAvailable().map(Tenant::getTenantId).orElse(null),
                    null);

            if( logger.isDebugEnabled() ) {
                logger.debug("Constructed command key: '" + commandKey + "'.");
            }

            return commandKey;
        }

        HystrixCommand.Setter build()
        {
            final String groupKey = HystrixUtil.getGlobalKey(commandClass);
            final String commandKey = getCommandKey();

            final HystrixCommandProperties.Setter commandProperties =
                HystrixCommandProperties
                    .Setter()
                    .withExecutionTimeoutInMilliseconds(6000)
                    .withCircuitBreakerEnabled(true)
                    .withCircuitBreakerSleepWindowInMilliseconds(6000)
                    .withFallbackEnabled(false);

            return HystrixCommand.Setter
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(groupKey))
                .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
                .andThreadPoolPropertiesDefaults(
                    HystrixThreadPoolProperties
                        .Setter()
                        .withCoreSize(10)
                        .withQueueSizeRejectionThreshold(100)
                        .withMaxQueueSize(100))
                .andCommandPropertiesDefaults(commandProperties);
        }
    }

    private static final CommandSetterBuilder setterBuilder = new CommandSetterBuilder(DestinationServiceCommand.class);

    private final XsuaaService xsuaaService;
    private final boolean propagateUser;

    private final DestinationService destinationService;
    private final String servicePath;

    private final boolean useProviderTenant;

    DestinationServiceCommand(
        @Nonnull final XsuaaService xsuaaService,
        final boolean propagateUser,
        @Nonnull final DestinationService destinationService,
        @Nonnull final String servicePath,
        final boolean useProviderTenant )
    {
        super(setterBuilder.build());

        this.xsuaaService = xsuaaService;
        this.propagateUser = propagateUser;

        this.destinationService = destinationService;
        this.servicePath = servicePath;

        this.useProviderTenant = useProviderTenant;
    }

    private AccessToken getAccessToken( final boolean propagateUser )
    {
        try {
            return xsuaaService.getServiceToken(DestinationService.SERVICE_NAME, propagateUser, useProviderTenant);
        }
        catch( final TokenRequestFailedException | TokenRequestDeniedException e ) {
            throw new DestinationAccessException(
                "Failed to get access token for " + DestinationService.SERVICE_NAME + " service.",
                e);
        }
    }

    @Override
    protected String run()
        throws DestinationAccessException
    {
        return destinationService.executeRequest(servicePath, getAccessToken(propagateUser));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy