Integration With Cloud Application Programming Model
This document outlines how you integrate the SAP Cloud SDK into an application based on the SAP Cloud Application Programming Model (referred to as CAP in the remainder).
While this document provides a general overview of this topic, we have published a practical tutorial on SAP Developers which illustrates all steps on a comprehensive example.
We provide a guide on how to leverage the traditional Spring deployment in conjunction with CAP. That guide is applicable for your project if you need to invoke BAPIs via the SAP Java Connector library.
Integration Steps
The following instructions assume that you have an existing CAP project that can be built successfully. Furthermore, we assume that you deploy your app to the SAP BTP, Cloud Foundry environment.
Add the SAP Cloud SDK Bill-of-Material
Add the SAP Cloud SDK Bill-of-Material (BOM) into the dependencyManagement
section of the root POM.
Here is the XML snippet:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sap.cloud.sdk</groupId>
<artifactId>sdk-bom</artifactId>
<version>use-latest-version-here</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
We recommend using the latest SAP Cloud SDK version always. Check out the release notes to see the release history.
By default, the SAP Cloud SDK archetypes reference the SAP Cloud SDK Bill-of-Material sdk-bom
, which manages dependency versions for all SAP Cloud SDK modules and transitive dependencies.
If you face dependency conflicts, you can instead try using the SAP Cloud SDK Modules Bill-of-Material sdk-modules-bom
in the dependencyManagement
section of your Maven POM file.
Add the SAP Cloud SDK Dependencies
Add the respective SAP Cloud SDK dependencies to the POM file under the srv
directory.
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-cf</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.sdk.s4hana</groupId>
<artifactId>s4hana-all</artifactId>
<exclusions>
<exclusion>
<groupId>com.sap.cloud.servicesdk</groupId>
<artifactId>odata-v2-lib</artifactId>
</exclusion>
</exclusions>
</dependency>
Please use the same exclusion also on any other OData V2 related dependencies from the SAP Cloud SDK you may be using.
Note that the version
tags can be omitted, because the SAP Cloud SDK BOM controls the version of all the SAP Cloud SDK modules.
That is, you only need to increase the version of the BOM and all modules get updated automatically.
The two mentioned dependencies are modules that cover a broad range of possible the SAP Cloud SDK use cases. You may choose a more fine-grained selection of the SAP Cloud SDK dependencies according to your specific use case.
Add the Integration Dependency
If your app uses multitenancy features and/or a protected backend, we have to integrate the tenant and user concepts of CAP and the SAP Cloud SDK.
We'll add a respective integration dependency to the POM file under the srv
directory (same place as the previous step).
<dependency>
<groupId>com.sap.cds</groupId>
<artifactId>cds-integration-cloud-sdk</artifactId>
</dependency>
You can learn more about how the multitenancy of the SAP Cloud SDK integrates with CAP in this article.
This step is only required if you are using CAP/CDS versions earlier than 1.23.0
.
Enable the Component Scan for SAP Cloud SDK Package
Let the Spring component scan crawl the SAP Cloud SDK package.
We'll annotate the Spring Boot application class which is annotated with @SpringBootApplication
as follows.
@ComponentScan({"com.sap.cloud.sdk", "com.mycompany.myapplication"})
@ServletComponentScan({"com.sap.cloud.sdk", "com.mycompany.myapplication"})
Make sure that you also add the package name of your application.
Wrap Asynchronous Calls
If your app uses asynchronous calls which spawn new threads or reuse pooled threads, the call must be decorated with the respective wrapper classes. This decoration is required to forward thread-specific information from the calling thread to the asynchronously running thread.
For this purpose, you need to use the RequestContextRunner
from CAP
Example:
EventContext context;
RequestContextRunner cdsContextRunner = context.getCdsRuntime().requestContext();
Callable<Object> task = () -> cdsContextRunner.run(() -> ... ));
The executeWith
methods of Accessor classes cannot be currently used to execute asynchronous operations in the CAP context.
Please note that the RequestScopedHttpClientCache
which is the default being used by the SAP Cloud SDK cannot work with CAP integration, please use TimeScopedHttpClientCache
instead for caching HttpClient
s.
In case you are using CAP/CDS versions earlier than 1.23.0
, additional steps are required.
Wrap asynchronous calls
You need to additionally wrap your calls using the ThreadContextExecutor
from the SAP Cloud SDK (refer to the ThreadContext documentation) in conjunction with the RequestContextRunner
from CAP.
Hence, the code snippet from above would look like:
EventContext context;
ThreadContextExecutor threadContextExecutor = new ThreadContextExecutor();
RequestContextRunner cdsContextRunner = context.getCdsRuntime().requestContext();
//If the operation returns something
Callable<Object> task = () -> cdsContextRunner.run(ctx -> {
return threadContextExecutor.execute(() -> operation());
});
//If the operation does not return something
Callable<Object> task = () -> cdsContextRunner.run(ctx -> {
threadContextExecutor.execute(() -> operation());
});
Now the SAP Cloud SDK is integrated with the CAP application. You can go ahead using the SAP Cloud SDK features, such as querying OData services.