- Kyma ✅
- Cloud Foundry ✅
A feature that will make your SaaS application even more valuable to your SaaS consumers, is an integration with other SAP solutions. This will allow your consumers to make use of their own data within your SaaS service offering and gain real business value out of it. For sure a SaaS solution can always offer an Excel upload or an online interface for maintaining tenant-specific data, but an automated backend integration is more than just a nice to have especially when dealing with constantly changing data sets.
In this part of the tutorial, you will learn how your SaaS consumers can connect an ABAP-based backend like SAP S/4HANA with their Consumer Tenant SaaS instance and push data into their Tenant database container in an automated fashion.
Important - The CAP payload size limitation for this sample has been increased to 50 MB. Please check the server.js file (click here) to remove or modify this setting if required. Keep in mind that when using SAP API Management, different file size limits apply and you will need to using streaming features to upload larger files.
While you already learned about the SaaS API in the Basic Version, the API calls in this part of the tutorial will not be triggered by a random external source anymore but will be directly sent from an SAP S/4HANA system. Using a scheduled job on the data provider side, the Tenants can constantly provide their users with the latest data input.
See the relevant part of the solution architecture below:
You will need a NetWeaver system that contains the Enterprise Procurement Model (EPM). The EPM model should be available in the NetWeaver stacks (EHP 2, > 7.3) and in ABAP Platforms (> 1809).
Hint - EPM is a sample data model containing sales and purchase orders for various products, which can be generated using a dedicated ABAP transaction. Please check if you can access the transaction SEPM_DG in your system, which is the respective Data Generator for the EPM model. Furthermore, please ensure the development package RS_TCO_EPM is available in the system as views from this package will be used by the sample code
-
You will need advanced authorizations in your system to e.g.,
- configure and HTTP destination in SM59.
- configure OAuth 2.0 clients in OA2C_CONFIG.
- develop in SE80 or the ABAP Development tools.
- maintain required SSL certificates in STRUST.
-
Your system needs to allow outbound HTTP connections to SAP BTP.
Feel free to generate some first sample data values in your EPM model using the SEPM_DG transaction.
To make sure your push setup is working properly, you might need to import additional SSL certificates to your ABAP backend. Depending on whether you're using a custom domain or a default SAP Kyma Subdomain for your API, please import the respective certificates to the SSL client SSL Client (Anonymous) and SSL client SSL Client (Standard) PSE using the STRUST transaction.
Kyma
Cloud Foundry
Especially in scenarios using a custom domain (e.g., with a CSR signed by Let's Encrypt) you might need to import additional certificates incl. missing Root certificates. This ensures secure and encrypted communication between your backend system and your API on SAP BTP. Check the detailed explanation in SAP Help (click here).
- Switch to change mode (Ctrl+F1)
- Double-click on "SSL client SSL Client (Anonymous)" in the navigation tree
- In the "Certificate" menu click on the "Import" button
- Use the file selector to select your SSL certificate (see screenshots below)
- Click the button with the green check-mark
- Once the certificate details are visible, click on "Add to Certificate List"
- Double-click on "SSL client SSL Client (Standard)" in the navigation tree
- Make sure the certificate details are still visible in the "Certificate" area in the lower right panel
- Click on "Add to Certificate List" to add the certificate
- Finish by clicking the "Save" button
You as a SaaS provider, but also your consumers can download their respective certificate right from within the browser (like Chrome) as you can see in the following screenshots:
Please use the trace files (Goto -> Trace File) in transaction SMICM to analyze certificate-related errors!
Create a new development package in ABAP Development Tools for Eclipse or using ABAP Development workbench (SE80). Give it a name like ZSUSAAS or another name of your choice.
5.1. Create an OAuth Client Profile in your ABAP development package named ZSUSAAS_PUSH_API (click to enlarge).
Select DEFAULT as the type. This Client Profile is required when setting up your OAuth Client in the next step.
5.2. In the Scopes section please add the uaa.resource scope.
6.1. Create a new OAuth Client in the web-based transaction OA2C_CONFIG. The default path for the respective transaction is https://<host_name>:<https_port>/sap/bc/webdynpro/sap/oa2c_config?sap-client=<client e.g. 100>
. Log in with a user authorized to create new OAuth Clients and click on Create ....
6.2. Enter the following values and choose OK.
-
OAuth 2.0 Client Profile:
ZSUSAAS_PUSH_API
or the name of the OAuth Client profile defined in the previous step -
Configuration Name:
SUSAAS_PUSH_API_S4
or another name of your choice -
OAuth 2.0 Client ID: Enter the clientid of the service binding created for the API service instance (click here)
Kyma
Cloud Foundry
6.3. On the Administration tab enter the client secret of the service key.
6.4. Under Authorization Server Settings, enter the URL for the authorization endpoint.
Take the uaa.url parameter of your service key, remove the https:// prefix and add /oauth/authorize
6.5. Under Authorization Server Settings, enter the URL for the token endpoint.
Take the uaa.url parameter of your service key, remove the https:// prefix and add /oauth/token
6.6. Under Access Settings, select the following settings and afterward, click on Save at the very top of the screen.
- Client Authentication: Basic
- Resource Access Authentication: Header Field
- Selected Grant Type: Client Credentials
Important - Note that the proxy settings must be configured beforehand.
6.7. Your configuration should look similar to the following (click to enlarge).
The ABAP logic pushing the EPM sample data to the SaaS API will make use of a destination defined in your NetWeaver system. Check the steps below to learn how to set up such a destination.
7.1. Open transaction SM59 and choose Create.
7.2. Enter a name like SUSAAS_PUSH_API for the RFC destination.
7.3. Select connection type G (HTTP Connection to External Server).
7.4. On the Technical Settings tab, enter the following data: - Target Host: apiUrl (not uaa.url!) parameter of your service key (without https:// prefix!) - Port: 443
Kyma
Cloud Foundry
7.5. On the Logon & Security tab provide the following settings:
- Check Do not use a user
- Set SSL to Active
- Check Do not use certificate for logon
7.6. Select OAuth Settings and provide the profile and configuration as follows:
Important - Setting the OAuth Settings within SM59 requires an SAP S/4HANA system of release 2021 or higher. For earlier releases, please check for blogs and tutorials explaining how to setup the OAuth2 flow as part of your ABAP coding. Search the community for Configuring OAuth 2.0 and Creating an ABAP Program That Uses OAuth 2.0 Client API to get an idea how to setup things in your system if required.
- Profile : ZSUSAAS_PUSH_API or the profile name you specified
- Configuration: SUSAAS_PUSH_API_S4 or the configuration you specified
7.7. Save your entries and click on Connection Test in the top left.
7.8. Make sure the test is successful and a code 200 is returned.
Your destination is now ready to be used from within the ABAP coding.
Let's now put the puzzle pieces together and push some data using the SaaS API and the connection defined in SM59. The following ABAP development objects can either be created in SAP GUI or by using the ABAP Development Tools.
Please go to your ABAP Development Tools in eclipse or use SE80 transaction in your SAP GUI to create two structures required for the upload process.
Important - Please double-check if the structure field names and types match with the corresponding target views EPM_V_PROD and EPM_V_SALES_DATA. We cannot guarantee consistency across all releases.
Structure ZSUSAAS_S_PRODUCTS_UPL
Description - Susaas Products Upload Structure
Component | Typing Method | Component Type | Data Type | Length | Decimals | Coordinate | Short Description |
---|---|---|---|---|---|---|---|
PRODUCT_ID | 1 Types | SNWD_PRODUCT_ID | CHAR | 10 | 0 | 0 | EPM: Product ID |
TYPE_CODE | 1 Types | SNWD_PRODUCT_TYPE_CODE | CHAR | 2 | 0 | 0 | EPM: Product Type Code |
CATEGORY | 1 Types | SNWD_PRODUCT_CATEGORY | CHAR | 40 | 0 | 0 | EPM: Product Category |
SUPPLIER_ID | 1 Types | SNWD_PARTNER_ID | CHAR | 10 | 0 | 0 | EPM: Business Partner ID |
TAX_TARIF_CODE | 1 Types | SNWD_PRODUCT_TAX_TARIF_CODE | INT1 | 3 | 0 | 0 | EPM: Product Tax Tariff Code |
MEASURE_UNIT | 1 Types | SNWD_QUANTITY_UNIT | UNIT | 3 | 0 | 0 | EPM: Quantity Unit |
WEIGHT_MEASURE | 1 Types | SNWD_WEIGHT_MEASURE | QUAN | 13 | 3 | 0 | EPM: Weight Measure |
WEIGHT_UNIT | 1 Types | SNWD_WEIGHT_UNIT | UNIT | 3 | 0 | 0 | EPM: Weight Unit |
CURRENCY_CODE | 1 Types | SNWD_CURR_CODE | CUKY | 5 | 0 | 0 | EPM: Currency Code |
PRICE | 1 Types | SNWD_UNIT_PRICE | CURR | 15 | 2 | 0 | EPM: Product Unit Price |
LANGU | 1 Types | (use Built-In Type) | CHAR | 1 | 0 | 0 | Language |
TEXT | 1 Types | SNWD_DESC | CHAR | 255 | 0 | 0 | EPM: Text field for names and descriptions |
Please also map the required Currency/quantity fields mapping as shown below.
Structure ZSUSAAS_S_SO_UPL
Description - Susaas Sales Order Upload Structure
Component | Typing Method | Component Type | Data Type | Length | Decimals | Coordinate | Short Description |
---|---|---|---|---|---|---|---|
SO_ID | 1 Types | SNWD_SO_ID | CHAR | 10 | 0 | 0 | EPM: Sales Order Number |
LIFECYCLE_STATUS | 1 Types | SNWD_SO_LC_STATUS_CODE | CHAR | 1 | 0 | 0 | EPM: Sales Order Lifecycle Status |
BILLING_STATUS | 1 Types | SNWD_SO_CF_STATUS_CODE | CHAR | 1 | 0 | 0 | EPM: Sales Order Confirmation Status |
DELIVERY_STATUS | 1 Types | SNWD_SO_OR_STATUS_CODE | CHAR | 1 | 0 | 0 | EPM: Sales Order Ordering Status |
SO_ITEM_POS | 1 Types | SNWD_SO_ITEM_POS | CHAR | 10 | 0 | 0 | EPM: Sales Order Item Position |
CURRENCY_CODE | 1 Types | SNWD_CURR_CODE | CUKY | 5 | 0 | 0 | EPM: Currency Code |
GROSS_AMOUNT | 1 Types | SNWD_TTL_GROSS_AMOUNT | CURR | 15 | 2 | 0 | EPM: Total Gross Amount |
TAX_AMOUNT | 1 Types | SNWD_TTL_TAX_AMOUNT | CURR | 15 | 2 | 0 | EPM: Total Tax Amount |
NET_AMOUNT | 1 Types | SNWD_TTL_NET_AMOUNT | CURR | 15 | 2 | 0 | EPM: Total Net Amount |
QUANTITY | 1 Types | SNWD_QUANTITY | QUAN | 13 | 3 | 0 | EPM: Quantity |
QUANTITY_UNIT | 1 Types | SNWD_QUANTITY_UNIT | UNIT | 3 | 0 | 0 | EPM: Quantity Unit |
DELIVERY_DATE | 1 Types | TIMESTAMPL | DEC | 21 | 7 | 0 | UTC Time Stamp in Long Form (YYYYMMDDhhmmssmmmuuun) |
PRODUCT_ID | 1 Types | SNWD_PRODUCT_ID | CHAR | 10 | 0 | 0 | EPM: Product ID |
CATEGORY | 1 Types | SNWD_PRODUCT_CATEGORY | CHAR | 40 | 0 | 0 | EPM: Product Category |
BP_ROLE | 1 Types | SNWD_BUSINESS_PARTNER_ROLE | CHAR | 3 | 0 | 0 | EPM: Business Partner Role |
BP_ID | 1 Types | SNWD_PARTNER_ID | CHAR | 10 | 0 | 0 | EPM: Business Partner ID |
COMPANY_NAME | 1 Types | SNWD_COMPANY_NAME | CHAR | 80 | 0 | 0 | EPM: Company Name |
TEXT | 1 Types | SNWD_DESC | CHAR | 255 | 0 | 0 | EPM: Text field for names and descriptions |
ITEM_ATP_STATUS | 1 Types | SNWD_SO_ITEM_ATP_STATUS_CODE | CHAR | 1 | 0 | 0 | EPM: Sales Order Item ATP Status |
COUNTRY | 1 Types | SNWD_COUNTRY | CHAR | 3 | 0 | 0 | EPM: Country Code |
FIRST_NAME | 1 Types | SNWD_FIRST_NAME | CHAR | 40 | 0 | 0 | EPM: First Name |
LAST_NAME | 1 Types | SNWD_LAST_NAME | CHAR | 40 | 0 | 0 | EPM: Last Name |
OVERALL_STATUS | 1 Types | SNWD_SO_OA_STATUS_CODE | CHAR | 1 | 0 | 0 | EPM: Sales Order Overall Status |
LANGUAGE | 1 Types | (use Built-In Type) | CHAR | 1 | 0 | 0 | Language |
Please also map the required Currency/quantity fields mapping as shown below.
Create a new ABAP Objects class in your ZSUAAS development package. You can find the required code snippet in the code sub-directory (click here).
Hint - This helper class is used in your sample programs to support the relevant upload process. It is a generic implementation that can be used to send data to different API endpoints using the same coding for various entities like in our case - Products and Sales Orders.
Class ZSUSAAS_CL_UPLOAD
(click here for the code)
The class provides a method GET_HTTP_CLIENT used to create an instance of the default ABAP HTTP Client feature, which allows you to send HTTP requests to the SaaS API using the connection defined in SM59. The POST_DATA_TO_API method is responsible for sending the dataset to the respective API endpoints using the HTTP client instance. The method implementation in this sample is very lean and can be enhanced based on your requirements to introduce features like packaging larger-scale datasets or proper error handling in case of erroneous requests. The CLOSE_CONNECTION method ensures that the API connection is closed again after sending the data to your SaaS APIs.
Feel free to scroll through the implementation to get a better understanding of what is happening under the hood when calling the method implementations from the programs which you import in the next steps.
In this sample application, we will use ABAP programs to upload the Product and Sales Order datasets available in the Enterprise Procurement Model. As mentioned at the beginning of this tutorial, feel free to generate new Sales Orders using the data generator transaction before doing your first data push.
For the data push implementation, please create two programs in your ZSUSAAS development package. You can find the respective sample coding in the code sub-directory.
Program ZSUSAAS_R_UPLOAD_PRODUCTS
(click here for the code)
Program ZSUSAAS_R_UPLOAD_SO
(click here for the code)
Feel free to scroll through the implementation to get a better understanding which EPM views are read, how the data is converted into the required JSON payload, and finally send to the SaaS API. The code is not very complex but please be aware, this is a very simple scenario, which is not supposed to handle scenarios like mass uploads or proper error handling (e.g. in case of duplicate key issues or connection problems).
Of special importance are the following lines of the coding. This is where the name of your SM59 destination is defined and the relevant endpoint for the respective dataset is declared. Please modify your code accordingly if you didn't follow the names proposed in this tutorial.
To test the SaaS Push API end-to-end, you can just simply execute the programs which you created in the previous step.
If you're not facing any error messages, your upload was probably successful. To check whether the data was successfully uploaded to the Tenant database container, you can log in to the respective Tenant of your SaaS application and check the available products (when creating a new assessment) or refer to the logs of the API service application instance in the Provider Subaccount.
To automate the push process of the latest EPM data, you can use the programs which you just created within a background job. To create a new background job, please go to transaction SM36 and follow the steps below for both programs defined above and your personal scheduling requirements (hourly, daily, weekly, ...).
10.1. Define a name for your background job like ZSUSAAS_UPLOAD_PRODUCTS. Set the priority to C and select the target application server.
10.2. By hitting Enter, you can define the first Step of your job. Select ABAP program and enter the name of your program like ZSUSAAS_R_UPLOAD_PRODUCTS. After clicking on Check, please save the step.
10.3. Go back to your job details.
10.4. Next you have to define a Start Condition for your job, which allows you to set up the scheduling.
10.5. As condition type select Date/Time and enter the first start date and time of your background job. Ensure the checkbox for Periodic Job is checked and then select Period Values to set up the schedule.
10.6. Decide in which repeated schedule you want to run your job. Click on Check and then save the settings.
10.7. Review and save your start condition to return to your job details.
10.8. You should now see that your job is properly configured.
10.9. Save the job to release and enable it.
10.10. You should see a success message confirming your job is released.
10.11. You can check the status of your job in the Job Selection. Make sure to set the correct filters, especially for the start date.
10.12. You will see the job in status Released in the Job Overview screen.
Please use the following links to find further information on the topics above:
- SAP Help - Enterprise Procurement Model
- SAP Help - Configuring OAuth 2.0 for AS ABAP
- SAP Help - SSL/TLS Trust Between Service Provider and AS ABAP
- SAP Help - Configuring an OAuth 2.0 Client in the AS ABAP
- SAP Help - Maintaining Remote Destinations
- SAP Help - System Security for SAP NetWeaver AS
- SAP Help - Transport Layer Security on SAP NetWeaver AS for ABAP
- SAP Help - Creating the HTTP Client
- SAP Help - Job Scheduling Explained