In June 2020 we have launched a brand new documentation portal which consolidates all the knowledge, feature documentation, comprehensive guides, video tutorials, troubleshooting, release notes, API documentation and more. Please, use it as a single reference point about SAP Cloud SDK. From now on it's the most complete and up to date source of information about the product.
This blog post outlines how a Java project following the Cloud Application Programming (CAP) Model can be adjusted so that it leverages the SAP Cloud SDK in version 3.
Introduction
A CAP project can be created from within the SAP Web IDE. Simply speaking, one defines CDS entities and service definitions which expose the entities as an OData API. The developer can register event listeners that are invoked upon interacting with the OData entities. Thereby, the developer implements custom logic and can influence the OData API response. For instance, the logic can enrich the returned OData entities with data fetched from other connected systems.
Additionally, one can let the Web IDE generate Virtual Data Model (VDM) classes that allow for type-safe access to an external OData API, such as from SAP S/4HANA.
By default, CAP projects use the SAP Cloud SDK in version 2 under the hood. In order to let the developer benefit from the
capabilities introduced in SAP Cloud SDK 3, it is desirable to adjust a CAP project so that it uses SAP Cloud SDK 3.
This blog post outlines adjustment steps that have been tested using a plain freshly generated CAP project. At the end, we have a CAP project where the latest features of the SAP Cloud SDK can be consumed.
Note: Depending on the complexity of your CAP project and the changes you applied to the dependencies and project structure, it can happen that not all of the explained steps work in exactly the same manner.
Which Projects does this Blog Post apply to
This blog post applies to CAP projects which are generated using the SAP Web IDE. They contain the two Maven modules
srv and
integration-tests. Also, the
pom.xml of the
srv module inherits from the following parent POM:
<parent>
<groupId>com.sap.cloud.servicesdk.prov</groupId>
<artifactId>projects-parent-odatav2</artifactId>
<version>1.XX.Y</version>
</parent>
Furthermore, when the developer inspects the project's dependency tree as follows:
mvn dependency:tree
and the developer encounters many occurrences of artifacts belonging to the SAP Cloud SDK 2, such as
com.sap.cloud.s4hana.cloudplatform:security-scp-cf:jar:2.19.0:compile, this indicates that still SAP Cloud SDK version 2 is used which means that the adjustment of the project is necessary.
Since this blog post mainly focuses on altering the project structure aiming that SAP Cloud SDK 3 is part of the dependency tree, we recommend that after conducting the adjustment steps outlined in this blog post, you continue adjusting your usages of the SAP Cloud SDK classes themselves as per the related
blog post.
Adjustment Steps
Starting Point
We prove that the application works by building and deploying them to the Cloud. The procedure of building and deploying to the Cloud environment is project-specific, therefore we do not go into the details here. It is important to ensure that the application works before the adjustment, to figure out later on if the adjustment caused an issue or if the issue was present already beforehand.
Rename Execution Identifier for Maven Enforcer Plugin
The developer opens the
pom.xml in the root level of the project and notices the
maven-enforcer-plugin. The execution id uses the outdated name of the SAP Cloud SDK:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M1</version>
<executions>
<execution>
<id>S/4HANA Cloud SDK Project Structure Checks</id>
<goals>
<goal>enforce</goal>
We rename the id to "SAP Cloud SDK Project Structure Checks".
Adjust Maven Artifacts
We open the
pom.xml in the
integration-tests module and replace the following Maven Artifacts:
<dependency>
<!-- Remove this outdated Group Identifier of SAP Cloud SDK 2 -->
<!-- <groupId>com.sap.cloud.s4hana.cloudplatform</groupId> -->
<!-- Add this new Group Identifier of SAP Cloud SDK 3 -->
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-cf</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- Remove this outdated Group Identifier of SAP Cloud SDK 2 -->
<!-- <groupId>com.sap.cloud.s4hana</groupId> -->
<!-- Add this new Group Identifier of SAP Cloud SDK 3 -->
<groupId>com.sap.cloud.sdk.s4hana</groupId>
<artifactId>s4hana-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- Remove this outdated Group Identifier and Artifact Identifier of SAP Cloud SDK 2 -->
<!-- <groupId>com.sap.cloud.s4hana</groupId> -->
<!-- <artifactId>testutil</artifactId> -->
<!-- Add this current Group Identifier and Artifact Identifier of SAP Cloud SDK 3 -->
<groupId>com.sap.cloud.sdk.testutil</groupId>
<artifactId>testutil-core</artifactId>
<scope>test</scope>
</dependency>
Introduce Bill-of-Material (BOM) of SAP Cloud SDK and Service SDK
We open the
pom.xml in the root level of the project and add the following Maven configuration inside the
project section:
<properties>
<!-- Use the latest versions here.-->
<!-- These are the latest versions at the time of this writing.-->
<com-sap-cloud-sdk.version>3.9.0</com-sap-cloud-sdk.version>
<com-sap-cloud-servicesdk.version>1.36.1</com-sap-cloud-servicesdk.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sap.cloud.sdk</groupId>
<artifactId>sdk-bom</artifactId>
<version>${com-sap-cloud-sdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud.servicesdk</groupId>
<artifactId>odata-v2-bom</artifactId>
<version>${com-sap-cloud-servicesdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Remove Parent POM
We open the
pom.xml in the module
srv and remove the reference to the parent POM:
<!-- Remove this section -->
<!--
<parent>
<groupId>com.sap.cloud.servicesdk.prov</groupId>
<artifactId>projects-parent-odatav2</artifactId>
<version>1.XX.Y</version>
</parent>
-->
Set Project Root POM as new Parent POM
We open the
pom.xml in the module
srv and add the reference to the room
pom.xml as parent POM:
<parent>
<artifactId>your-artifact-id</artifactId>
<groupId>your-group-id</groupId>
<version>your-version</version>
</parent>
Note that the values of
artifactId,
groupId and
version are application-specific. You can open the root
pom.xml to obtain those values, when in doubt.
Set Java Language Level for Maven Compiler Plugin
We open the
pom.xml in the module
srv and configure the Java language level to be Java 8. For this purpose, we introduce the following tags in the section
properties:
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
This step is necessary because before the adjustment the language level got inherited from the parent POM. After the adjustment this parent POM is not used anymore, therefore we have to add this configuration explicitly.
Add Missing Dependencies
We open the
pom.xml in the module
srv and add the following dependencies inside the section
dependencies:
<dependency>
<groupId>com.sap.cloud.servicesdk.prov</groupId>
<artifactId>odata-v2-prov</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.servicesdk</groupId>
<artifactId>odata-v2-connectivity-sdk3</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
<scope>provided</scope>
</dependency>
Adjust Testutil Class
Open the class
Testutil in the module
integration-tests and remove the following lines in the method
createDeployment:
.addClasses(RequestContextServletFilter.class, RequestContextCallable.class)
.addClass(TenantRequestContextListener.class)
.addClass(UserRequestContextListener.class)
.addClass(DestinationsRequestContextListener.class)
Instead, insert the following lines:
.addClass(TenantThreadContextListener.class)
.addClass(PrincipalThreadContextListener.class)
.addClass(HttpClientsThreadContextListener.class)
Optional: Remove Virtual Data Model Classes
In case your project consumes an external data model by leveraging the Virtual Data Model (VDM) classes of the SAP Cloud SDK, you can remove them for the moment to make the application compile. We will recreate them in a subsequent step.
These classes resider in the file path
srv/src/main/java/vdm.
Examine Maven Dependency Tree
Given that all steps mentioned above are conducted correctly, the dependency tree of the CAP project does reference SAP Cloud SDK version 3.
The developer invokes again
mvn dependency:tree
and we do see SAP Cloud SDK 3 artifacts, such as
com.sap.cloud.sdk.cloudplatform:security-scp-cf:jar:3.9.0:compile
Make Rest-Assured Version Explicit
We open the
pom.xml in the module
integration-tests and mention an explicit version of the module
rest-assured:
<!--
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
-->
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<!-- This line gets added. Use the latest version. -->
<version>4.1.2</version>
<scope>test</scope>
Optional: Include OData VDM Generator Explicitly
Given that you had removed the VDM classes in a previous step, you resume adding the OData VDM Generator provided by the SAP Cloud SDK to your build lifecycle. That will generate the VDM classes based on the SAP Cloud SDK Version 3.
Open the
pom.xml in the
srv module and insert the following Maven plugin configuration:
<plugin>
<groupId>com.sap.cloud.sdk.datamodel</groupId>
<artifactId>odata-generator-maven-plugin</artifactId>
<version>${com-sap-cloud-sdk.version}</version>
<executions>
<execution>
<id>generate-consumption</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputDirectory>${project.basedir}/external/edmx</inputDirectory>
<outputDirectory>${project.build.directory}/vdm</outputDirectory>
<deleteOutputDirectory>true</deleteOutputDirectory>
<packageName>my.vdm.businesspartner</packageName>
</configuration>
</execution>
</executions>
</plugin>
Note that you might need to adjust the package name as per your project-specific circumstances as well as that the usage of the variable
com-sap-cloud-sdk.version ensures that you always use a consistent SAP Cloud SDK version throughout the whole project.
Build and Test CAP Project
The developer invokes
mvn clean install
on the command line. This compiles the project and executes the integration tests.
When we see "build success" we can be assured that the adjustment was successful.
Adjust SAP Cloud SDK Usage
All preceding steps focused on altering the project structure so that the project's dependency tree contains SAP Cloud SDK 3. We recommend going through the
blog post outlining how to adjust your application code to consume the latest SAP Cloud SDK capabilities.
Conclusion
This blog post touched upon the Cloud Application Programming (CAP) Model, its relation to the SAP Cloud SDK and why an adjustment to the latest SAP Cloud SDK 3 is desirable.
Based on that, it outlined in detail how the adjustment of such a CAP project has to be performed.
From there on, the developers working on the CAP project can benefit from the many improvements the SAP Cloud SDK provides as of version 3.