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

com.sap.cloud.sdk.cloudplatform.connectivity.GetAuthHeadersCommand 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 java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.annotation.Nullable;

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.connectivity.exception.DestinationOAuthTokenException;
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.frameworks.hystrix.Command;
import com.sap.cloud.sdk.frameworks.hystrix.HystrixUtil;
import com.sap.core.connectivity.api.authentication.AuthenticationHeader;
import com.sap.core.connectivity.api.authentication.AuthenticationHeaderProvider;
import com.sap.core.connectivity.api.configuration.DestinationConfiguration;

import lombok.Data;

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

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

        private String getCommandKey( final String destinationName, final URI requestUri )
        {
            final String commandKey =
                HystrixUtil.getTenantIsolatedKey(commandClass) + HystrixUtil.getDelimiter() + destinationName;

            if( logger.isDebugEnabled() ) {
                logger.debug(
                    "Constructed command key: '"
                        + commandKey
                        + "'. Destination: '"
                        + destinationName
                        + "', request URI: '"
                        + requestUri
                        + "').");
            }

            return commandKey;
        }

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

            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(GetAuthHeadersCommand.class);

    private final ScpNeoDestination destination;

    @Nullable
    private final URI requestUri;

    GetAuthHeadersCommand( final ScpNeoDestination destination, @Nullable final URI requestUri )
    {
        super(setterBuilder.build(destination.getName(), requestUri));

        this.destination = destination;
        this.requestUri = requestUri;
    }

    @Override
    protected List
run() throws DestinationAccessException { @Nullable final DestinationConfiguration destinationConfiguration = destination.getDestinationConfiguration(); if( destinationConfiguration == null ) { if( logger.isDebugEnabled() ) { logger.debug("Skipping fetching of authentication headers: DestinationConfiguration is null."); } return Collections.emptyList(); } return getAuthenticationHeaders(destinationConfiguration); } private AuthenticationHeaderProvider getAuthenticationHeaderProvider() throws DestinationAccessException { final Optional requestContext = RequestContextAccessor.getCurrentRequestContext(); if( !requestContext.isPresent() ) { throw new DestinationAccessException( "Failed to get " + AuthenticationHeaderProvider.class.getSimpleName() + ": 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?"); } try { final Optional> property = requestContext.get().getProperty( ScpNeoDestinationsRequestContextListener.PROPERTY_AUTHENTICATION_HEADER_PROVIDER); if( !property.isPresent() ) { throw new DestinationAccessException( "Failed to get " + AuthenticationHeaderProvider.class.getSimpleName() + ": " + RequestContext.class.getSimpleName() + " property '" + ScpNeoDestinationsRequestContextListener.PROPERTY_AUTHENTICATION_HEADER_PROVIDER + "' is not present. " + "Please ensure that " + ScpNeoDestinationsRequestContextListener.class.getSimpleName() + " is available on the class path."); } @Nullable final Exception exception = property.get().getException(); if( exception != null ) { throw new DestinationAccessException( "Failed to get " + AuthenticationHeaderProvider.class.getSimpleName() + ".", exception); } return (AuthenticationHeaderProvider) property.get().getValue(); } catch( final RequestContextPropertyException e ) { throw new DestinationAccessException( "Failed to get " + AuthenticationHeaderProvider.class.getSimpleName() + ": failed to get " + RequestContext.class.getSimpleName() + " property.", e); } } private List
getAuthenticationHeaders( final DestinationConfiguration destinationConfiguration ) throws DestinationAccessException { final AuthenticationHeaderProvider authenticationHeaderProvider = getAuthenticationHeaderProvider(); try { final List
authenticationHeaders = new ArrayList<>(); switch( destination.getAuthenticationType() ) { case PRINCIPAL_PROPAGATION: { authenticationHeaders .add(transformHeader(authenticationHeaderProvider.getPrincipalPropagationHeader())); break; } case OAUTH2_CLIENT_CREDENTIALS: { authenticationHeaders.add( transformHeader( authenticationHeaderProvider.getOAuth2ClientCredentialsHeader(destinationConfiguration))); break; } case OAUTH2_SAML_BEARER_ASSERTION: { authenticationHeaders.addAll( transformHeaders( authenticationHeaderProvider .getOAuth2SAMLBearerAssertionHeaders(destinationConfiguration))); break; } case APP_TO_APP_SSO: { authenticationHeaders.add( transformHeader( authenticationHeaderProvider.getApptoAppSSOHeader( (requestUri != null ? requestUri : destination.getUri()).toString(), destinationConfiguration))); break; } case SAP_ASSERTION_SSO: { authenticationHeaders.add( transformHeader(authenticationHeaderProvider.getSAPAssertionHeader(destinationConfiguration))); break; } case NO_AUTHENTICATION: case BASIC_AUTHENTICATION: case CLIENT_CERTIFICATE_AUTHENTICATION: case INTERNAL_SYSTEM_AUTHENTICATION: default: // authentication headers must not be retrieved via the authentication header API break; } return authenticationHeaders; } catch( final IllegalArgumentException | IllegalStateException e ) { if( e.getMessage() != null && e.getMessage().contains("OAuthTokenGenerationException") ) { throw new DestinationOAuthTokenException(destination.getName(), e); } throw new DestinationAccessException(e); } } private Header transformHeader( final AuthenticationHeader authenticationHeader ) { return new Header(authenticationHeader.getName(), authenticationHeader.getValue()); } private Collection
transformHeaders( final Iterable authenticationHeaders ) { final List
headers = new ArrayList<>(); for( final AuthenticationHeader authenticationHeader : authenticationHeaders ) { headers.add(transformHeader(authenticationHeader)); } return headers; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy