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

com.sap.cloud.sdk.s4hana.connectivity.ErpConfigContext Maven / Gradle / Ivy

/*
 * Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
 */

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

import java.util.Locale;

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

import org.slf4j.Logger;

import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationType;
import com.sap.cloud.sdk.cloudplatform.connectivity.GenericDestination;
import com.sap.cloud.sdk.cloudplatform.connectivity.WithDestinationName;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationTypeNotSupportedException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.servlet.LocaleAccessor;
import com.sap.cloud.sdk.s4hana.serialization.SapClient;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

/**
 * This class provides a context for transparently connecting to an SAP S/4HANA system via different protocols such as
 * HTTP and RFC.
 * 

* An {@link ErpConfigContext} allows to define or obtain the {@link SapClient} and {@link Locale} that is used. In * addition, it defines the names of the destinations that are relevant to connect to the ERP via different protocols * which can require separate destinations. *

* The following table shows which protocols are supported based on the existence and configuration of destinations: *

* * * * * * * * * * * * * * * * * * * * * * *
Destination typeSupported protocols
d1 = {@link #getDestinationName()}d2 = {@link #getDestinationNameRfc()}
HTTPanyHTTP via d1
RFCanyRFC via d1
HTTPRFCHTTP via d1, RFC via d2 *
*

* The following table shows which protocols are required for different query types to certain editions of S/4HANA. * Here, the usual setup for S/4HANA Cloud is to only use one single HTTP destination d1 (supporting all * query types), while for S/4HANA on-premise systems, depending on the required query type, either a single RFC * destination d1, or an HTTP destination d1 and an additional RFC destination d2 can * be used to configure the connection to the respective system: *

* * * * * * * * * * * * * * * * * * *
SAP S/4HANAODataQueryBapiQueryRfcQuery
CloudHTTPHTTPHTTP
On-PremiseHTTPRFCRFC
*/ @EqualsAndHashCode @ToString public class ErpConfigContext implements ConfigContext, WithDestinationName { private static final Logger logger = CloudLoggerFactory.getSanitizedLogger(ErpConfigContext.class); /** * The name suffix for an additional destination that is considered for RFC communication if * {@link ErpConfigContext#getDestinationName()} refers to an HTTP destination. This suffix is appended to the given * destination name unless the name of the additional RFC destination is explicitly defined. This is required to * transparently support both HTTP and RFC communication via these two respective destinations (a destination can * only support either HTTP or RFC). */ public static final String DESTINATION_NAME_SUFFIX_RFC = "_RFC"; /** * The default name of the destination property holding the {@link SapClient} for {@link DestinationType#HTTP}. */ public static final String DEFAULT_SAP_CLIENT_PROPERTY = "sap-client"; /** * The default name of the destination property holding the {@link Locale} for {@link DestinationType#HTTP}. */ public static final String DEFAULT_LOCALE_PROPERTY = "sap-language"; /** * The default name of the destination property holding the {@link SapClient} for {@link DestinationType#RFC}. */ public static final String DEFAULT_SAP_CLIENT_PROPERTY_RFC = "jco.client.client"; /** * The default name of the destination property holding the {@link Locale} for {@link DestinationType#RFC}. */ public static final String DEFAULT_LOCALE_PROPERTY_RFC = "jco.client.lang"; /** * The name of the destination to be used for connecting to the ERP via HTTP or RFC. Defaults to * {@link ErpDestination#getDefaultName()}. */ @Nonnull @Getter private final String destinationName; /** * The name of the additional destination that is considered for connecting to the ERP via the RFC protocol if * {@link #getDestinationName()} refers to an HTTP destination. This is required to transparently support both HTTP * and RFC communication via these two respective destinations (a destination can only support either HTTP or RFC). * Defaults to {@link ErpDestination#getDefaultNameRfc()} = {@link ErpDestination#getDefaultName()} + * {@link #DESTINATION_NAME_SUFFIX_RFC}. */ @Nonnull @Getter private final String destinationNameRfc; /** * The {@link SapClient} to be used for connecting to the ERP. If not provided upon construction, this value is read * from the respective property of destination {@link ErpDestination#getDefaultName()}. Defaults to * {@link SapClient#DEFAULT} otherwise. */ @Nonnull @Getter private final SapClient sapClient; /** * The {@link Locale} to be used for connecting to the ERP. If not provided upon construction, this value is read * from the respective property of destination {@link ErpDestination#getDefaultName()}. Defaults to * {@link Locale#getDefault()} otherwise. */ @Nonnull @Getter private final Locale locale; /** * Creates an ERP configuration context. * * @param destinationName * The name of the ERP destination that can be used for HTTP or RFC communication. If this is * {@code null}, the default name defined by {@link ErpDestination#getDefaultName()} is used. * * @param destinationNameRfc * The name of the additional destination that is considered for connecting to the ERP via the RFC * protocol if {@code destinationName} refers to an HTTP destination. This is required to transparently * support both HTTP and RFC communication via these two respective destinations (a destination can only * support either HTTP or RFC). If this is {@code null}, the default name is defined as: * destinationNameRfc = destinationName + * {@link #DESTINATION_NAME_SUFFIX_RFC}. * * @param sapClient * The SAP client to be used. If this is {@code null}, the destination configuration of * {@code destinationName} is used to read the property with the name specified by * {@code sapClientProperty}. If this destination property does not exist, {@link SapClient#DEFAULT} is * used. * * @param sapClientProperty * The name of the destination property to be used for reading the SAP client. If this is {@code null}, * the following default property name is used: *
    *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* * @param locale * The locale to be used. If this is {@code null}, first, the destination configuration of * {@code destinationName} is used to read the property with the name specified by {@code localeProperty} * . If this fails, the locale defined by {@link LocaleAccessor#getCurrentLocale()} is used. * * @param localeProperty * The name of the destination property to be used for reading the locale. If this is {@code null}, the * following default property name is used: *
    *
  • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* * @throws DestinationAccessException * If the configuration for the given destination cannot be found. */ public ErpConfigContext( @Nullable final String destinationName, @Nullable final String destinationNameRfc, @Nullable final SapClient sapClient, @Nullable final String sapClientProperty, @Nullable final Locale locale, @Nullable final String localeProperty ) throws DestinationAccessException { this.destinationName = destinationName == null ? ErpDestination.getDefaultName() : destinationName; this.destinationNameRfc = destinationNameRfc == null ? this.destinationName + DESTINATION_NAME_SUFFIX_RFC : destinationNameRfc; GenericDestination destination = null; if( sapClient == null ) { destination = DestinationAccessor.getGenericDestination(this.destinationName); final String propertyName; if( sapClientProperty == null ) { final DestinationType destinationType = destination.getDestinationType(); switch( destinationType ) { case HTTP: propertyName = DEFAULT_SAP_CLIENT_PROPERTY; break; case RFC: propertyName = DEFAULT_SAP_CLIENT_PROPERTY_RFC; break; case MAIL: case LDAP: default: throw new DestinationTypeNotSupportedException(this.destinationName, destinationType); } } else { propertyName = sapClientProperty; } @Nullable final String property = destination.getPropertiesByName().get(propertyName); if( property == null ) { if( logger.isInfoEnabled() ) { logger.info( "Unable to retrieve SAP client from destination property '" + propertyName + "'. Falling back to default SAP client. " + "To specify the SAP client, set the property on destination '" + this.destinationName + "' or provide the SAP client as explicit argument."); } } this.sapClient = property != null ? new SapClient(property) : SapClient.DEFAULT; } else { this.sapClient = sapClient; } if( locale == null ) { final String propertyName; if( localeProperty == null ) { if( destination == null ) { destination = DestinationAccessor.getGenericDestination(this.destinationName); } final DestinationType destinationType = destination.getDestinationType(); switch( destinationType ) { case HTTP: propertyName = DEFAULT_LOCALE_PROPERTY; break; case RFC: propertyName = DEFAULT_LOCALE_PROPERTY_RFC; break; case MAIL: case LDAP: default: throw new DestinationTypeNotSupportedException(this.destinationName, destinationType); } } else { propertyName = localeProperty; } Locale fallback = null; try { if( destination == null ) { destination = DestinationAccessor.getGenericDestination(this.destinationName); } final String localeString = destination.getPropertiesByName().get(propertyName); if( localeString != null ) { fallback = Locale.forLanguageTag(localeString.replace('_', '-')); } } catch( final DestinationNotFoundException | DestinationAccessException e ) { if( logger.isInfoEnabled() ) { logger.info("Unable to retrieve locale from destination property '" + propertyName + "'.", e); } } if( fallback == null ) { fallback = LocaleAccessor.getCurrentLocale(); if( logger.isInfoEnabled() ) { logger.info( "Falling back to locale '" + fallback + "'. To specify the locale, set the property on destination '" + this.destinationName + "' or provide the locale as explicit argument."); } } this.locale = fallback; } else { this.locale = locale; } } /** * Creates an ERP configuration context. * * @param destinationName * The name of the ERP destination that can be used for HTTP or RFC communication. If this is * {@code null}, the default name defined by {@link ErpDestination#getDefaultName()} is used. * * @param sapClient * The SAP client to be used. If this is {@code null}, the destination configuration of * {@code destinationName} is used to read the property with the name specified by * {@code sapClientProperty}. If this destination property does not exist, {@link SapClient#DEFAULT} is * used. * * @param sapClientProperty * The name of the destination property to be used for reading the SAP client. If this is {@code null}, * the following default property name is used: *
    *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* * @param locale * The locale to be used. If this is {@code null}, first, the destination configuration of * {@code destinationName} is used to read the property with the name specified by {@code localeProperty} * . If this fails, the locale defined by {@link LocaleAccessor#getCurrentLocale()} is used. * * @param localeProperty * The name of the destination property to be used for reading the locale. If this is {@code null}, the * following default property name is used: *
    *
  • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* * @throws DestinationAccessException * If the configuration for the given destination cannot be found. */ public ErpConfigContext( @Nullable final String destinationName, @Nullable final SapClient sapClient, @Nullable final String sapClientProperty, @Nullable final Locale locale, @Nullable final String localeProperty ) throws DestinationAccessException { this(destinationName, null, sapClient, sapClientProperty, locale, localeProperty); } /** * Creates an ERP configuration context. * * @param destinationName * The name of the ERP destination that can be used for HTTP or RFC communication. If this is * {@code null}, the default name defined by {@link ErpDestination#getDefaultName()} is used. * * @param sapClient * The SAP client to be used. If this is {@code null}, the destination configuration of * {@code destinationName} is used to read the property with the following default property name: *
    *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* If this destination property does not exist, {@link SapClient#DEFAULT} is used. * * @param locale * The locale to be used. If this is {@code null}, first, the destination configuration of * {@code destinationName} is used to read the property with the following default property name: *
    *
  • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* If this fails, the locale defined by {@link LocaleAccessor#getCurrentLocale()} is used. * * @throws DestinationAccessException * If the configuration for the given destination cannot be found. */ public ErpConfigContext( @Nullable final String destinationName, @Nullable final SapClient sapClient, @Nullable final Locale locale ) throws DestinationAccessException { this(destinationName, sapClient, null, locale, null); } /** * Creates an ERP configuration context using the current {@link Locale}. * * @param destinationName * The name of the ERP destination that can be used for HTTP or RFC communication. If this is * {@code null}, the default name defined by {@link ErpDestination#getDefaultName()} is used. * * @param sapClient * The SAP client to be used. If this is {@code null}, the destination configuration of * {@code destinationName} is used to read the property with the following default property name: *
    *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* If this destination property does not exist, {@link SapClient#DEFAULT} is used. */ public ErpConfigContext( @Nullable final String destinationName, @Nullable final SapClient sapClient ) { this(destinationName, sapClient, null, null, null); } /** * Creates an ERP configuration context using the default property of this destination *
    *
  • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* or {@link SapClient#DEFAULT} if this property does not exist, as well as the current {@link Locale}. * * @param destinationName * The name of the ERP destination that can be used for HTTP or RFC communication. If this is * {@code null}, the default name defined by {@link ErpDestination#getDefaultName()} is used. */ public ErpConfigContext( @Nullable final String destinationName ) { this(destinationName, null, null, null, null); } /** * Creates an ERP configuration context using the default ERP destination name * {@link ErpDestination#getDefaultName()} and the current {@link Locale}. * * @param sapClient * The SAP client to be used. If this is {@code null}, the destination configuration of * {@code destinationName} is used to read the property with name {@link #DEFAULT_SAP_CLIENT_PROPERTY}. * If this destination property does not exist, {@link SapClient#DEFAULT} is used. */ public ErpConfigContext( @Nullable final SapClient sapClient ) { this(null, sapClient, null, null, null); } /** * Creates an ERP configuration context using the default ERP destination name * {@link ErpDestination#getDefaultName()} and the default SAP client property of this destination: *
    *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* If this destination property does not exist, {@link SapClient#DEFAULT} is used. * * @param locale * The locale to be used. If this is {@code null}, first, the destination configuration of * {@code destinationName} is used to read the default locale property: *
    *
  • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
  • *
  • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
  • *
* If this fails, the locale defined by {@link LocaleAccessor#getCurrentLocale()} is used. */ public ErpConfigContext( @Nullable final Locale locale ) { this(null, null, null, locale, null); } /** * Creates the default ERP configuration context using *
    *
  • default ERP destination name {@link ErpDestination#getDefaultName()}, *
  • default SAP client property of this destination *
      *
    • {@link #DEFAULT_SAP_CLIENT_PROPERTY} for {@link DestinationType#HTTP} or
    • *
    • {@link #DEFAULT_SAP_CLIENT_PROPERTY_RFC} for {@link DestinationType#RFC}
    • *
    * if available - otherwise {@link SapClient#DEFAULT}. *
  • default locale property of this destination *
      *
    • {@link #DEFAULT_LOCALE_PROPERTY} for {@link DestinationType#HTTP} or
    • *
    • {@link #DEFAULT_LOCALE_PROPERTY_RFC} for {@link DestinationType#RFC}
    • *
    * if available - otherwise locale {@link LocaleAccessor#getCurrentLocale()}. *
*/ public ErpConfigContext() { this(null, null, null, null, null); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy