Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Sidney
Product and Topic Expert
Product and Topic Expert
This blog post is following up on the SAP Cloud SDK for Java (version 4.0.0 just released) introduction tutorial on SAP Developers Community, Create a Simple Cloud Foundry App Using SAP Cloud SDK , which provides a hands-on to create a very simple servlet retrieving Business Partner information from an OData service system, and then deploy the application onto Business Technology Platform, Cloud Foundry environment. The purpose is to provide a procedure-concentrated guide and expand the details on each step, especially the steps to connect to the OData service, as a compliment to the original tutorial.

Although there are multiple alternatives to implement the original tutorial, here in this blog post we will only show the path that I took. Specifications:

  • backend OData system: SAP S/4HANA Cloud

  • deploy environment: SAP BTP, Cloud Foundry

  • local machine: macOS (Terminal)

  • IDE: Eclipse (with maven plugin)


References


Original tutorial (in java) https://developers.sap.com/group.s4sdk-cloud-foundry.html

SAP Cloud SDK document  https://sap.github.io/cloud-sdk/docs/java/getting-started

M2Eclipse http://www.eclipse.org/m2e/

Environment Setup


➡️ Install JAVA 8


First you need to check if java is installed.
java --version

I got the result:
openjdk 18 2022-03-22
OpenJDK Runtime Environment SapMachine (build 18+36-sapmachine)
OpenJDK 64-Bit Server VM SapMachine (build 18+36-sapmachine, mixed mode)

There might be multiple versions installed, and this version is not supporting the project. So I still need to install the correct version.

If your operating system is macOS or Linux, you can use Homebrew to install java, first update brew,
brew update
brew tap AdoptOpenJDK/openjdk

and then install Java 8
brew install adoptopenjdk8 --cask

➡️ Install Maven


Check if maven is installed.
mvn --version

Result,
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
Maven home: /Users/xyz/Workspace/apache-maven-3.8.5
Java version: 18, vendor: SAP SE, runtime: /Library/Java/JavaVirtualMachines/sapmachine-jdk-18.jdk/Contents/Home
Default locale: en_CN, platform encoding: UTF-8
OS name: "mac os x", version: "12.4", arch: "aarch64", family: "mac"

If not, first download the maven latest release and then install it.

In my case maven is installed but the default java version is not correct. This is because the Java home is still the old one.
echo $JAVA_HOME

get result:
/Library/Java/JavaVirtualMachines/sapmachine-jdk-18.jdk/Contents/Home

So after finding the java home, set new java home. In my case:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home

Now both the java version and maven default java version are correct.
java -version
# result
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.292-b10, mixed mode)

mvn --version
# result
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
Maven home: /Users/xyz/Workspace/apache-maven-3.8.5
Java version: 1.8.0_292, vendor: AdoptOpenJDK, runtime: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre
Default locale: en_CN, platform encoding: UTF-8


OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"

If you want to make the change permanent, write it in /usr/local/etc/mavenrc or /etc/mavenrc

➡️ Install eclipse and eclipse maven plugin


Install eclipse by following the steps on this page.

In my case eclipse is installed, so open the eclipse, go to the Eclipse Marketplace and search for the maven plugin: M2Eclipse - Eclipse IDE integration for Maven. For terminal you can use the Terminal desktop app or install a terminal plug-in in eclipse.



➡️ Install cf cli


Install the command-line interface for Cloud Foundry, see here.

In my case it is installed, check version,
cf -v

get result
cf version 8.1.0+034d929d7.2022-01-03

Initiate the project


➡️ Generate project from archetype


Use maven to generate a Cloud SDK project, from the "hello world" archetype,
mvn archetype:generate -DarchetypeGroupId=com.sap.cloud.sdk.archetypes -DarchetypeArtifactId=scp-cf-tomee -DarchetypeVersion=RELEASE

and then fill in the requested info in the interactive session, e.g. name - firstapp. If you want to use the default setting then just hit return.

The archetype is a TomEE-based project, scp-cf-tomee, latest version 4.0.0.


Import the newly created project into eclipse.


➡️ Build the project


Go into the project root path and build the project,
mvn clean package

with this command an *.war file will be generated.

You can run the project locally, with TomEE container as its target runtime,
mvn tomee:run -pl application

and then visit  http://localhost:8080/hello

➡️ Deploy to cf


It can run on both neo and cloud foundry. First login to cf with the user credentials and API endpoint URL, in my case I found https://api.cf.sap.hana.ondemand.com in my Subaccount.
cf login -a https://api.cf.sap.hana.ondemand.com -u sindy.zhan@sap.com -p XYZ

Then specify the ORG and SPACE, and deploy the app,
cf push

You can check the deployed app and its route, which you use to access the app.
cf apps
# result
Getting apps in org XYZ / space XYZ as sindy.zhan@sap.com...

name requested state processes routes
firstapp started web:1/1 firstapp-fearless-chipmunk-vf.cfapps.sap.hana.ondemand.com

In my case, I can visit the app via https://firstapp-fearless-chipmunk-vf.cfapps.sap.hana.ondemand.com


Click HelloWorldServlet, or add a path /hello at the end of the URL to see the "hello world" greeting.

Retrieve data from the backend


The above steps bring us a demo hello world module, displaying static text on the webpage. Now we will create a new module to connect to the backend system.

➡️ Add business partner servlet


Create BusinessPartnerServlet, to retrieve all persons (a specific kind of business partner) with their name and a few additional properties. You can copy and paste the code from the original tutorial, which needs some changes according to your scenario, or you can follow this blog post and copy and paste the code below.
package com.sap.cloud.sdk.tutorial;

import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
import com.sap.cloud.sdk.datamodel.odata.client.exception.ODataException;
import com.sap.cloud.sdk.datamodel.odata.helper.Order;

import com.sap.cloud.sdk.s4hana.connectivity.DefaultErpHttpDestination;
import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestination;
import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartner;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;

@WebServlet("/businesspartners")
public class BusinessPartnerServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(BusinessPartnerServlet.class);

private static final String CATEGORY_PERSON = "1";
private final ErpHttpDestination destination = DestinationAccessor.getDestination("MyErpSystem").asHttp().decorate(DefaultErpHttpDestination::new);

@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
try {
final List<BusinessPartner> businessPartners =
new DefaultBusinessPartnerService()
.getAllBusinessPartner()
.select(BusinessPartner.BUSINESS_PARTNER,
BusinessPartner.LAST_NAME,
BusinessPartner.FIRST_NAME,
BusinessPartner.IS_MALE,
BusinessPartner.IS_FEMALE,
BusinessPartner.CREATION_DATE)
.filter(BusinessPartner.BUSINESS_PARTNER_CATEGORY.eq(CATEGORY_PERSON))
.orderBy(BusinessPartner.LAST_NAME, Order.ASC)
.top(200)
.executeRequest(destination);

logger.info(String.format("Found %d business partner(s).", businessPartners.size()));

response.setContentType("application/json");
response.getWriter().write(new Gson().toJson(businessPartners));
} catch (final ODataException e) {
logger.error(e.getMessage(), e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write(e.getMessage());
}
}
}

Connect to OData service


➡️ Choose OData service


Here the OData service is SAP S/4HANA cloud with Business Partner OData V2 service.

➡️ Expose APIs on SAP S/4HANA cloud


To expose APIs on SAP S/4HANA cloud, then you should create communication users, and create destination

0. search for communication scenario


On SAP API Business Hub, we find the information for Business Partner (A2X): https://api.sap.com/api/API_BUSINESS_PARTNER/overview

You can click on the business document to see APIs and their sample playloads.

Here we will use a sample URL read Business Partner master data:







GET /sap/opu/odata/SAP/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner='900023122')

You can also find the Communication Scenario we need: Business Partner, Customer and Supplier Integration(SAP_COM_0008)


 

And then In S/4HANA Cloud, Fiori Launchpad, we complete the rest of the steps to expose APIs.

1. create communication user


Search for communication user > open “Maintain Communication Users” tile  > click New > fill in the user name,


Do remember to note down the generated password for later use.

Then click Create.

2. create communication system


Navigate to Communication Systems > New > input System ID and System Name.

In the Technical Data > General, fill in Host Name. In my case, the host name to my S/4HANA Cloud system is my301481.s4hana.ondemand.com, so I set my host name to be my301481-api.s4hana.ondemand.com


Choose the Communication User we just created for New Inbound Communication User


And for the Outbound Communication, choose the default customer client certificate


 

Save the changes.

3. create communication arrangement


Search for and navigate to Communication Arrangements > create New > fill in the Communication Scenario that we need SAP_COM_0008.

Select Communication System we just created, and the associated Communication User automatically comes in.

In the Inbound Services section, we can find the Service URL for Business Partner (A2X) OData V2








Business Partner (A2X) OData V2 https://my301481-api.s4hana.ondemand.com/sap/opu/odata/sap/API_BUSINESS_PARTNER

In the Outbound Services section, dis-select the outbound services that are active by default.


Save it.

~. test it on postman (or other tools)


This is an optional step.

If we want to read the list of business partners, create request:
GET https://my301481-api.s4hana.ondemand.com/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner

And fill in the authorization: Authorization > Type > choose Basic Auth > fill in communication user as Username and Password

 

From the response body we can find a Business Partner ID, and use it to read the corresponding business partner details. In my case I check the Business Partner with the ID 1000154,
GET https://my301481-api.s4hana.ondemand.com/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('1000154')


➡️ Configurate destination on BTP


If you want to deploy the app to Cloud Foundry, go to your BTP Cockpit > Subaccount > Connectivity > Destinations.

Create a new destination with the name of MyErpSystem (which is hardcoded in BusinessPartnerServlet.java), URL to be https:// = host name, and choose BasicAuthentication, with the Communication User credentials to be User and Password.


After creation, you can test the connection. Every HTTP status code below 500 is treated as successful.



Deploy to the cloud


Now go back from BTP Cockpit to local Terminal, and do the deployment.

➡️ Create two service instance


Create service instance for the destination service and xsuaa. You can do it in cf cli or in Cockpit, here we provide the cf cli commands:
cf create-service destination lite my-destination
cf create-service xsuaa application my-xsuaa

➡️ Bind the app with two newly created service instances


To bind the two newly created service instances to your application when it is deployed, adapt the manifest.yml file by adding the two instances to the services section at the end.

In this case, the two services are commented in manifest.yml so now uncomment them.



➡️ Deploy to SAP BTP Cloud Foundry


Now deploy the application again.
mvn clean install
cf push

Use the same URL we can visit the application, but this time a new servlet can be accessed via path /businesspartners


The rest of the tutorial is to add a local integration test in the integration-test module, which doesn't affect the above steps so I will not add them to this blog post. If necessary, I will complete them later.
7 Comments