The SAP Cloud SDK offers some basic functionality that helps with connecting to other systems and services like SAP S/4HANA Cloud.
The SAP Cloud SDK introduces the general concept of a
Destination which holds basic information about how to connect to such a system.
That could for instance be a
url, a username, and password for basic authentication or some custom headers.
This concept is integrated with the Destination Service that is available on the SAP Business Technology Platform. If the application has a service binding to this service in place the SAP Cloud SDK will provide access to these destinations.
In general destinations are accessed through the
This will look up the destination in the destination service if the application is running on SAP Business Technology Platform. Other sources like the environment variables are also considered.
To minimize the runtime overhead of finding destinations, the SAP Cloud SDK uses caching to internally maintain a list of already retrieved destinations.
Therefore, subsequent calls to
DestinationAccessor.getDestination("my-destination"); will be served from that cache instead of performing the look up over and over again.
Cache entries will automatically be invalidated 5 minutes after their initial creation.
We provide support for the following authentication types on SAP BTP, Cloud Foundry environment.
|Authentication Type||Parameter Name|
By default, the
DestinationAccessor is tenant aware.
If a tenant is available, it will be used to access the destination service on behalf of that tenant.
If no destination is found in the tenant-specific destination service, the SAP Cloud SDK will try to get it using the service binding of the application.
This default retrieval strategy can be overridden by passing options to the destination loader as follows:
See the section on destination options below.
Depending on the use case, one needs to wrap the accessed destination before issuing a request to a system. This is to make sure all required destination properties are correctly set before invoking the actual request.
In case of HTTP connections one needs to wrap the retrieved destination as
This method ensures that the required destination properties are all set to make the HTTP connection. With the resulting destination instance depending on the use case one can run HTTP queries for OData or REST.
Similarly, for BAPI endpoints you need to use
If your destination is exposing an SAP S/4HANA On-premise service via a Cloud Connector you need to decorate the destination with
- This ensures the mapping of all SAP S/4HANA properties like
sap-localeas HTTP request headers.
- In case Principal Propagation is specified as an authentication type for the destination the SAP Cloud SDK will automatically apply it.
The SAP Cloud SDK offers convenient ways to create a destination at runtime and register it so that it will be available via
This is especially useful when working in a local environment.
Destinations configured in the destination service are not available in a local setting and have to be mocked.
The SAP Cloud SDK offers a
MockUtil class that is capable of injecting destinations into the
This helps with keeping production and test code nicely separated.
There are more overloads of the mocking on the
MockUtil class that you can use.
Refer to these tutorial steps on how to mock destinations for local development and testing.
The above is useful for testing but not suited for productive code. If you want to register custom destinations in your productive code you can use the following API:
By default, the
DestinationAccessor is using a
DestinationLoaderChain that comprises multiple loaders.
These are e.g. a loader to get destinations from the destination service and a loader that reads destinations from environment variables.
appendDestinationLoader() will add the provided loader at the end of such a chain.
That means the new loader can operate as a fallback.
prependDestinationLoader() to add it at the beginning if you would like it to take precedence.
setLoader() to replace all existing loaders.
You can add headers that are sent for any request over destinations. You can implement custom logic that defines which headers are sent under which circumstances.
Let's imagine, you want to send an API token via a request header with any calls made over any destination in your whole application.
The SAP Cloud SDK offers the interface
DestinationHeaderProvider which defines the method
At runtime, while preparing an outbound request, the SAP Cloud SDK will use all implementations of that interface which have been registered via the Java ServiceLoader mechanism (see below).
For each registered implementation it invokes the method
getHeaders(DestinationRequestContext) and appends the returned headers to the currently prepared request.
Implement the Interface
To implement your custom destination header provider, you need to implement the interface
getHeaders provides access to the request specific context.
The method argument of type
DestinationRequestContext lets you access the general properties over which the currently prepared request will be issued.
Depending on your logic to determine headers, you can read the following data types:
DestinationProperties getDestination()(e.g. the general destination name).
URI getRequestUri()(e.g. the request specific query parameters)
Here is one simple example implementation which returns the same header for each request:
The SAP Cloud SDK uses the Service Loader mechanism of Java to look up the
DestinationHeaderProvider implementations at runtime.
To let your custom implementation be found, you need to provide a configuration file as resource in the folder
Name this resource file as the interface
com.sap.cloud.sdk.cloudplatform.connectivity.DestinationHeaderProvider and mention the fully-qualified class name of your custom implementation.
You can refer to several implementations by putting their fully qualified class names on separate lines.
Place the new folder + file in your resources folder.
In a Maven project the resource folder is typically
For example, if your custom implementation is named
ApiTokenHeaderProvider in the package
com.example, the configuration should be as follows:
- File path & name:src/main/resources/META-INF/services/com.sap.cloud.sdk.cloudplatform.connectivity.DestinationHeaderProvider
- File content:com.example.ApiTokenHeaderProvider
To fetch all destinations from the Destination Service, you need to make a call to
The method queries the Destination Service API and retrieves all the destinations available at the service instance and sub-account level.
In case there is a destination available on both the levels with the same name, then this method prioritizes the destination at the service instance level.
Below is the sample call to
In the above call
destinationLoader needs to be an instance of
By default, the
TimeLimiter resilience pattern aborts requests to the Destination Service on Cloud Foundry after 6 seconds.
If your app requires more time when fetching destinations, you may create your own
ScpCfDestinationLoader instance by:
This operation overrides the default timeout duration so that you are free to choose whatever value fits your needs.
You may register your
destinationLoader within the
That way, all future requests to the Destination Service will use the increased timeout duration.
You need to build a
DestinationOptions object and pass it as a parameter.
It defines how Destinations Service is queried.
In a simple application without provider/subscriber setup, your initial configuration is as simple as:
For a provider/subscriber setup, a retrieval strategy must be chosen according to your particular use case from:
Here is an example for
You can similarly use other retrieval options.
When testing your app on localhost instead of SAP BTP, you require some configuration steps to make the destination retrieval work.
This section refers to the maintenance of HTTP destinations. Refer to the documentation about BAPI/RFC communication concerning the maintenance of RFC destinations for local deployment.
Works for SAP Business Application Studio too
The configuration procedures outlined here work too when you launch your app "locally" inside SAP Business Application Studio. It does not matter that the app does not run on your own machine.
To better understand the configuration steps, we'll outline shortly how destination retrieval works when running your app on SCP. Thereafter, we'll outline the configuration procedures in detail.
By default, the SAP Cloud SDK uses a set of so-called destination loaders in a given order when searching for a destination via the
The first destination loader attempts to find the requested destination in the environment variable
Here is an example value:
You can configure multiple destinations with that approach. Note that the value of the environment variable is a JSON array, so you can add further entries into it.
If the previous lookup was not successful, the next destination loaders examine the environment variable
VCAP_SERVICES to see if the SAP BTP destination service is bound.
If so, the SAP Cloud SDK queries the SAP BTP destination service for the destination configuration per the requested destination name.
In case the destination is of proxy type
OnPremise, the SAP Cloud SDK performs an additional query to the SAP BTP connectivity service to obtain further proxy information and an authorization token.
Maintain the destination configuration via the environment variable
See the example value above for reference.
Destinations With Proxy Type
We have to some perform configuration steps to tell the SAP Cloud SDK how to access the SAP BTP destination service and connectivity service.
Are your client and server located on the same Network?
If your localhost (client) resides in the same network zone as the target system (server) you can access it directly.
Configuration of SAP BTP connectivity services is not needed.
All you have to do is creating a destination via environment variable
How to create the
VCAP_SERVICES representation depends on whether the Cloud Application Programming (CAP) Model is used.
- CAP is used
- CAP is not used
VCAP_SERVIES environment variable on the shell or operating system level.
Copy the value of that environment variable from your app which is deployed to SCP.
Create the file
default-env.json in your project's root and supply the
VCAP_SERVICES value you copied beforehand so that the file looks similar to the following shortened example:
Furthermore, add the dependency
com.sap.cds:cds-integration-cloud-sdk to your POM file:
For certain authentication types i.e.
OAuth2ClientCredentials there is an API that eliminates the need to manually create a destination in the CF account for connecting to services.
ScpCfServiceDestinationLoader.buildClientCredentialsMapping method creates a mapping for loading a destination and provides JSON paths for all required destination properties.
For certain services (only SAP BTP Workflow service for now), we provide further convenience that skips the need to provide the
The SAP BTP connectivity service builds the connection between SAP BTP and the On-premise network. That is why it has strong built-in restrictions to allow it only to be called from within SCP. If you call the connectivity service from your local machine, you will encounter a connection timeout. We'll therefore apply port forwarding via SSH to simulate that your localhost plays the cloud app.
- Deploy your app to the SAP BTP once.
- Enable SSH access to your app container with the
- Inspect the value of the entry
VCAP_SERVICESand take note of the values of the fields
We'll refer to these values as proxy-port and proxy-host hereafter.
- Create an SSH session to your app container with the following command and let the session opened:
- Replace the value of the field
Now your local setup is ready to consume an On-premise HTTP destination.