There are five cloud-native qualities: availability, elasticity, evolvability, scalability, and resilience. A good programming model and platform makes it easier for applications to score high on these qualities.

SAP Business Technology Platform (SAP BTP), with its platform services offerings, does a lot of heavy lifting to bring these cloud qualities to life. Still, it’s left to the application to implement the services and interfaces offered by SAP BTP. This results in lots of boilerplate code, which is an antipattern to efficient programming.

This is where the SAP Cloud SDK comes into the picture. SAP Cloud SDK offers libraries to ease the development of cloud applications on SAP BTP. These libraries communicate with other SAP solutions and services, such as SAP S/4HANA Cloud, SAP SuccessFactors solutions, and OData services, just to name a few.

2023_05_003.png?width=1922&name=2023_05_003.png&profile=RESIZE_710x

In other words, SAP Cloud SDK is your one-stop shop to overcome regulation programming challenges while building side-by-side extension applications on SAP BTP. At the same time, SAP Cloud SDK is fully compatible with the SAP Cloud application programming model (see https://cap.cloud.sap/docs/), which is SAP’s recommended approach to developing enterprise-grade services and applications on SAP BTP. You can download the SAP Cloud SDK at https://developers.sap.com/topics/cloud-sdk.html.

The SAP Cloud SDK comes with two variants—one for Java and one for JavaScript/Type-Script—and provides libraries, project templates, and a continuous delivery pipeline that you can use immediately.

Now, let’s touch on some of the details of how SAP Cloud SDK makes development and delivery of extension applications on SAP BTP so much more convenient. We’ll consider a simple SAP S/4HANA Cloud side-by-side extension application that displays business information that it fetches from an SAP S/4HANA Cloud system in real time, by consuming the respective public OData API, published on SAP API Business Hub (https://api.sap.com).

At a minimum, this application will need to perform the following actions, in addition to its own local application and data-fetching logic:

  • Connect with SAP S/4HANA Cloud
  • Log in to the tenant with the right authentication keys
  • Consume the needed public API with the required authorizations in place

Let’s see how the SAP Cloud SDK helps in achieving this.

Connectivity

SAP BTP provides the destination service, using which your app can reach an SAP S/4HANA Cloud tenant (or any other cloud service or system).

To use the destination service, you have to carry out the following steps:

  1. Retrieve login credentials from environment variables stored in the destination service.
  2. Using these login credentials, generate a JSON web token (JWT) through the SAP BTP user account and authentication (UAA). Add this JSON web token to the HTTP request header for authentication.
  3. Formulate the service endpoint you wish to call and send the HTTP request.

That is, to call an external system, you construct the HTTP request manually by adding the respective headers and security information manually.

In addition, you also need to perform all tasks related to the handling of the HTTP request, such as building the request URL, establishing the connection, handling the response, and parsing it.

With the SAP Cloud SDK, however, you can get the same result in a single line of code by using the DestinationAccessor class of the SDK that gives you an instance of the SAP BTP destination service:

 

final ErpHttpDestination destination =

   DestinationAccessor

   .getDestination("MyErpSystem")

   .asHttp()

   .decorate(DefaultErpHttpDestination::new);

 

Now you can use this destination instance in your OData call without the need to carry out the manual steps as stated previously.

Authentication

Every application needs to be secure. SAP BTP, Cloud Foundry environment helps you make your application secure by providing an application router (AppRouter) that does the following:

  • Serves as the single entry point for your application that can comprise of multiple microservices. Any incoming request needs to be abstracted from the complexity arising from the several microservices at play. AppRouter does just that by acting as a reverse proxy and dispatching incoming requests to the right microservice.
  • Manages the authentication flow for the application by initiating an OAuth2 flow with the extended services for user account and authentication (XSUAA) service of SAP BTP, Cloud Foundry environment. The XSUAA is an SAP-specific extension of Cloud Foundry’s UAA service to handle user authentication and authorization with SAP’s standards in place. To achieve this, the XSAA service fetches a JSON web token that embodies the user credentials and which application scopes he or she possesses. For a detailed explanation, see the tutorial available at https://developers.sap.com/tutorials/s4sdk-secure-cloudfoundry.html.

With the SAP Cloud SDK, you can achieve much more. For example, using the getCurrentToken method of the AuthTokenAccessor class, you can get the current authorization token, which further contains the JSON web token from the authorization header of the HTTP request.

Similarly, the getCurrentTenant method of the TenantAccessor class gives you access to the current tenant from different sources, such as the JSON web token in the authorization header or the bound XSUAA instance. In failing to do so, it provides elegant exception handling.

In summary, using SAP Cloud SDK libraries gives you convenient access to a number of XSUAA parameters that you would have had to manually fetch otherwise. For further information, visit https://developers.sap.com/topics/cloud-sdk.html.

API Consumption

Now that the user knows where to go (Destination) and has been successfully authenticated (AppRouter), she or he needs to get the required information for further processing.

To achieve this, SAP S/4HANA Cloud provides public APIs through the SAP API Business Hub. Let’s now discuss how the SAP Cloud SDK makes consumption of these APIs far simpler than otherwise would be the case.

We’ll look at the Business Partner OData API (API_BUSINESS_PARTNER) as our example. You can find it at the SAP API Business Hub at https://api.sap.com/api/API_BUSINESS_PARTNER/resource.

To access this API in your cloud application, you need to get the exact API semantics and traverse through the exposed entities and attributes. Programmatically, this may pose a challenge as you have to switch between the API description and the programming environment, with frequent manual context switching.

To enable easy API consumption with type-safe and fluent programmatical access, SAP offers the SAP Cloud SDK, which comes with API-specific libraries. These libraries are class representations of these APIs that you may import in your application and use directly in a type-safe manner. In our example API (API_BUSINESS_PARTNER), the corresponding library class is DefaultBusinessPartnerService, also known as the SAP Cloud SDK VDM, which implements the BusinessPartnerService interface. This, and all other library classes, representing all public APIs of SAP S/4HANA, are available as standard in the SAP Cloud SDK.

Now that we’ve taken a brief look at the value that the SAP Cloud SDK brings to development of side-by-side extensions, let’s bring it all together in the next section.

Build the Application Logic for Resilience

You’ve seen the connectivity, authentication, and API consumption capabilities of the SAP Cloud SDK. Now let’s put it into action.

Recall how you accessed the SAP BTP destination service through the SAP Cloud SDK libraries.

 

final ErpHttpDestination destination =

   DestinationAccessor

   .getDestination("MyErpSystem")

   .asHttp()

   .decorate(DefaultErpHttpDestination::new);

 

You may now use this destination to retrieve information from SAP S/4HANA through the SAP Cloud SDK VDM directly (DefaultBusinessPartnerService).

However, connections to remote systems are often unstable. Many things can go wrong between your request for data and the response, such as temporary system unavailability or broken network nodes. In such situations, we always recommend making your call in a resilient manner.

In short, resilience is the ability of your application to elegantly handle failure and not go down when one of the downstream processes fails to respond in a timely manner.

With the SAP Cloud SDK, you can wrap your calls into a resilient one by using the ResilienceDecorator library. To do so, start by configuring your resilient call using the ResilienceConfiguration class.

 

myResilienceConfig = ResilienceConfiguration

   .of(BusinessPartnerService.class)

   .isolationMode(ResilienceIsolationMode

   .TENANT_AND_USER_OPTIONAL)

   .timeLimiterConfiguration(ResilienceConfiguration

   .TimeLimiterConfiguration.of()

       .timeoutDuration(Duration.ofMillis(10000)))

   .bulkheadConfiguration(ResilienceConfiguration

   .BulkheadConfiguration.of().maxConcurrentCalls(20));

 

In this configuration, among other configuration choices, we have specified a timeout duration of one second, with no more than 20 concurrent calls. You can adapt these parameters according to the needs of your application.

Next, we encapsulate the actual call to the BusinessPartnerService, in a new method called run, like this:

 

final List<BusinessPartner> run {

return businessPartnerService

.getAllBusinessPartner()

.select(BusinessPartner.BUSINESS_PARTNER,

BusinessPartner.LAST_NAME,

BusinessPartner.FIRST_NAME,

BusinessPartner.IS_MALE,

BusinessPartner.IS_FEMALE,

BusinessPartner.CREATION_DATE)

.execute(destination);

 

Now, with myResilienceConfig, we call a chosen method of the ResilienceDecorator class (here we use the executeSupplier method).

 

   List<BusinessPartner> = ResilienceDecorator

       .executeSupplier(this::run, myResilienceConfig, e ->

       { return Collections.emptyList(); }

   );

 

Note the use of the run method, which makes the actual call to the BusinessPartnerService VDM library.

A word about the BusinesPartnerService: it follows the builder pattern and works with the execute method that takes the given destination as input.

For simplicity, we have omitted statements for class imports, requisite variable declarations, and exception handling. For a complete example, visit https://developers.sap.com/tutorials/s4sdk-resilience.html.

In practice, you can achieve much more. For example, you can add various query options while fetching the date, like this:

 

   .filter(BusinessPartner.BUSINESS_PARTNER_CATEGORY

       .eq(CATEGORY_PERSON))

   .orderBy(BusinessPartner.LAST_NAME, Order.ASC)

   .top(200)

   .execute(destination);

 

Now with the businessPartners object, you can perform all CRUD operations, including deep insert. In addition, if you have a custom OData service, you can use the VDM generator of SAP Cloud SDK to generate your OData service-specific library. For Java projects, this means a new Maven dependency with some configuration. Thereafter, you generate your library with a simple mvn clean install command. The only input you need is the API descriptor file in edmx format. To see end-to-end instructions, please visit https://blogs.sap.com/2018/04/30/deep-dive-10-with-sap-s4hana-cloud-sdk-generating-java-vdm-for-s4hana-custom-odata-service/

Once your library has been generated, you may use it as you would use any other library available in the standard SAP Cloud SDK.

This content was originally posted on the SAP PRESS Blog and has been adapted from a section of the book SAP S/4HANA Architecture by Thomas Saueressig, Tobias Stein, Jochen Boeder, and Wolfram Kleis. Used with permission of SAP PRESS. All rights reserved.

Votes: 0
E-mail me when people leave their comments –

I work for SAP PRESS, the world's leading SAP publisher.

You need to be a member of ERPcommunity.com to add comments!

Join ERPcommunity.com

MEMBERSHIP IS FREE!

Recent SAP Jobs




ERPcommunity.com is a 7LinksWeb.com project. You don't have to be big to be noticed.