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

com.sap.cloud.sdk.cloudplatform.connectivity.ScpNeoDestinationFacade 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 static com.sap.cloud.sdk.cloudplatform.connectivity.DestinationRetrievalStrategy.ALWAYS_PROVIDER;
import static com.sap.cloud.sdk.cloudplatform.connectivity.DestinationRetrievalStrategy.ALWAYS_SUBSCRIBER;
import static com.sap.cloud.sdk.cloudplatform.connectivity.DestinationRetrievalStrategy.PLATFORM_DEFAULT;
import static com.sap.cloud.sdk.cloudplatform.connectivity.DestinationRetrievalStrategy.SUBSCRIBER_THEN_PROVIDER;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

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

import org.slf4j.Logger;

import com.google.common.collect.Sets;
import com.google.gson.JsonObject;
import com.sap.cloud.account.TenantContext;
import com.sap.cloud.sdk.cloudplatform.CloudPlatform;
import com.sap.cloud.sdk.cloudplatform.CloudPlatformAccessor;
import com.sap.cloud.sdk.cloudplatform.ScpNeoCloudPlatform;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;
import com.sap.cloud.sdk.cloudplatform.exception.CloudPlatformException;
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.ScpNeoTenant;
import com.sap.cloud.sdk.cloudplatform.tenant.Tenant;
import com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor;
import com.sap.core.connectivity.api.configuration.ConnectivityConfiguration;
import com.sap.core.connectivity.api.configuration.DestinationConfiguration;

/**
 * Facade providing access to destinations on SAP Cloud Platform Neo.
 * 

* In addition to reading destinations via the SAP CP Neo destination service API , this class provides the ability to * read HTTP destination information from the environment variable "destinations". The environment variable is expected * to be in JSON format (see {@link AbstractDestinationFacade}). */ public class ScpNeoDestinationFacade extends AbstractDestinationFacade { private static final Logger logger = CloudLoggerFactory.getLogger(ScpNeoDestinationFacade.class); private final Set destinationNames = Sets.newConcurrentHashSet(); private ConnectivityConfiguration getConnectivityConfiguration() throws DestinationAccessException { final Optional requestContext = RequestContextAccessor.getCurrentRequestContext(); if( !requestContext.isPresent() ) { throw new DestinationAccessException( "Failed to get " + ConnectivityConfiguration.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_CONNECTIVITY_CONFIGURATION); if( !property.isPresent() ) { throw new DestinationAccessException( "Failed to get " + ConnectivityConfiguration.class.getSimpleName() + ": " + RequestContext.class.getSimpleName() + " property '" + ScpNeoDestinationsRequestContextListener.PROPERTY_CONNECTIVITY_CONFIGURATION + "' 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 " + ConnectivityConfiguration.class.getSimpleName() + ".", exception); } return (ConnectivityConfiguration) property.get().getValue(); } catch( final RequestContextPropertyException e ) { throw new DestinationAccessException( "Failed to get " + ConnectivityConfiguration.class.getSimpleName() + ": failed to get " + RequestContext.class.getSimpleName() + " property.", e); } } private DestinationConfiguration getDestinationConfiguration( final String destinationName ) throws DestinationAccessException, DestinationNotFoundException { final ConnectivityConfiguration connectivityConfiguration = getConnectivityConfiguration(); try { final DestinationRetrievalStrategy strategy = DestinationAccessor.getRetrievalStrategy(destinationName); DestinationConfiguration destinationConfiguration = null; if( strategy.equals(PLATFORM_DEFAULT) ) { destinationConfiguration = connectivityConfiguration.getConfiguration(destinationName); } else { if( strategy.equals(ALWAYS_SUBSCRIBER) || strategy.equals(SUBSCRIBER_THEN_PROVIDER) ) { destinationConfiguration = connectivityConfiguration.getConfiguration(getCurrentAccountId(), destinationName); } if( strategy.equals(ALWAYS_PROVIDER) || (destinationConfiguration == null && strategy.equals(SUBSCRIBER_THEN_PROVIDER)) ) { destinationConfiguration = connectivityConfiguration.getConfiguration(getProviderAccountId(), destinationName); } } if( destinationConfiguration == null ) { throw new DestinationNotFoundException(destinationName); } return destinationConfiguration; } catch( final IllegalArgumentException | IllegalStateException e ) { throw new DestinationAccessException( "Failed to access configuration for destination '" + destinationName + "'.", e); } } /** * {@inheritDoc} */ @Nonnull @Override public Class getGenericDestinationClass() { return ScpNeoGenericDestination.class; } /** * {@inheritDoc} */ @Nonnull @Override public Class getDestinationClass() { return ScpNeoDestination.class; } /** * {@inheritDoc} */ @Nonnull @Override public Class getRfcDestinationClass() { return ScpNeoRfcDestination.class; } /** * {@inheritDoc} */ @Override public void declareDestinations( @Nonnull final Collection destinationNames ) { this.destinationNames.addAll(destinationNames); } private void warnIfEnvironmentVariableIsUsed() { if( logger.isWarnEnabled() ) { logger.warn( "Environment variable '" + AbstractDestinationFacade.VARIABLE_DESTINATIONS + "' is set. " + "Destinations will only be read from this variable. " + "Unset this variable to read destinations from the destination service on SAP Cloud Platform."); } } /** * {@inheritDoc} */ @Nonnull @Override public GenericDestination getGenericDestination( @Nonnull final String destinationName ) throws DestinationNotFoundException, DestinationAccessException { // Note: we use a local variable that references JsonObject to make sure that // the maven-dependency-plugin correctly detects the usage of Gson here. final Map destinationsFromEnvironmentVariable = getDestinationsFromEnvironmentVariable(); if( destinationsFromEnvironmentVariable != null ) { warnIfEnvironmentVariableIsUsed(); return super.getGenericDestination(destinationName); } final DestinationConfiguration destinationConfiguration = getDestinationConfiguration(destinationName); final ScpNeoDestinationParser destinationParser = new ScpNeoDestinationParser(destinationConfiguration); return new ScpNeoDestinationFactory(destinationConfiguration).create(destinationParser); } /** * {@inheritDoc} */ @Nonnull @Override public Map getGenericDestinationsByName() throws DestinationAccessException { if( getDestinationsFromEnvironmentVariable() != null ) { warnIfEnvironmentVariableIsUsed(); return getDestinationsFromEnvironmentVariable(new ScpNeoDestinationFactory()); } if( logger.isDebugEnabled() ) { logger.debug("Resolving destinations by names: " + destinationNames + "."); } final Map result = new HashMap<>(); for( final String destinationName : destinationNames ) { final DestinationConfiguration destinationConfiguration = getDestinationConfiguration(destinationName); try { final ScpNeoDestinationParser destinationParser = new ScpNeoDestinationParser(destinationConfiguration); final GenericDestination destination = new ScpNeoDestinationFactory(destinationConfiguration).create(destinationParser); result.put(destinationName, destination); if( logger.isDebugEnabled() ) { logger.debug( String.format( "Successfully added %s destination '%s' to destination list.", destination.getDestinationType().toString(), destination.getName())); } } catch( final DestinationNotFoundException e ) { if( logger.isWarnEnabled() ) { logger.warn( "Failed to add destination '" + destinationName + "' to the result of getDestinationsByName(): destination not found. " + "This indicates a missing or incorrect destination configuration on Cloud platform side. " + "Correct the configuration of this destination or remove its declaration if obsolete.", e); } } } if( logger.isDebugEnabled() ) { logger.debug(String.format("Resolved %d destinations.", result.size())); } return result; } @Nonnull private String getCurrentAccountId() { final Tenant tenant = TenantAccessor.getCurrentTenant(); if( tenant instanceof ScpNeoTenant ) { final TenantContext tenantContext = ((ScpNeoTenant) tenant).getTenantContext(); return tenantContext.getTenant().getAccount().getId(); } else { throw new CloudPlatformException( "The current tenant is not an instance of " + ScpNeoTenant.class.getSimpleName() + ". Please make sure to specify a dependency to com.sap.cloud.s4hana.cloudplatform:tenant-scp-neo."); } } @Nonnull private String getProviderAccountId() { final CloudPlatform platform = CloudPlatformAccessor.getCloudPlatform(); if( platform instanceof ScpNeoCloudPlatform ) { return ((ScpNeoCloudPlatform) platform).getProviderAccountId(); } else { throw new CloudPlatformException( "The current Cloud platform is not an instance of " + ScpNeoCloudPlatform.class.getSimpleName() + ". Please make sure to specify a dependency to com.sap.cloud.s4hana.cloudplatform:core-scp-neo."); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy