Using Joule’s Async Feature to Communicate with a Custom BTP App

Estimated read time 9 min read

Today, we are going to use Joule’s asynchronous (async) feature to establish communication between Joule and a custom BTP app.
Joule has a limitation when handling responses that take longer than
45 seconds, so we need to enable the async feature to properly support long-running responses.

Step 1: Understand the Requirements

Before starting, please review the help documentation:
Asynchronous API Requests

The prerequisites are critical:

To enable asynchronous API requests:
• IAS-enabled subaccount
    o The BTP subaccount must be integrated with SAP Identity Authentication Service (IAS)
• For callback support your backend has to:
    o Perform the actual asynchronous task.
    o Send a callback to Joule once complete.
• A trust configuration must be set up between the backend system and Joule:
    o This requires implementation efforts on Joule integration configuration
    o To trigger this, create an AIPS requirement on the Joule component in Jira

If your account is not IAS-enabled yet, check this guide:
SCI Developer Guide – Intro

If you are trying to enable the async feature of Joule on a SAP LoB product, you need to create an AIPS Jira ticket.

Step 2: App2App with IAS

To enable the async feature with IAS, we use the App2App approach.
If you are interested, learn the concepts of Inbound and Outbound App2App for SAP DAS:

Inbound

Outbound

Once familiar, you can start setting up trust between Joule and IAS by following:
IAS App2App Dev Setup

Our scenario is slightly simpler than the reference document.

In the documentation, the flow is: 

 Joule <-> devflow_proxy_app <-> downstream app (SAP Build Workzone)

Our goal is:

 Joule <-> custom app

This means we do not need a proxy layer in the IAS console.
We can directly link Joule’s Cloud Identity Service to the custom app’s Cloud Identity Service.
In my case, my custom app’s CIS is named as “giaIas”.

Step 3: Configure the Destination for Joule

Now, create a Destination at the subaccount level for Joule to consume.
Because we do not have a middle layer for redirecting, we do not need below property in destination configuration:

 tokenService.body.resource=urn:sap:identity:application:provider:name:proxy-to-target

Use the following destination settings: 

Name=DestionationName
Type=HTTP
URL=<target-api-url>
ProxyType=Internet
Authentication=OAuth2JWTBearer
clientId=<custom_app_cis-clientID>
clientSecret=<custom_app_cis-clientSecret>
tokenServiceURL=<ias-host>/oauth2/token
x_user_token.jwks_uri=<ias-host>/oauth2/certs
apptoapp=true
tokenService.body.token_format=jwt
tokenService.body.client_id=<custom_app-clientID>
tokenService.addClientCredentialsInBody=false
tokenServiceURLType=Dedicated

With this configuration, the Outbound setup is complete.
Joule can now send requests to this destination and forward them to your target URL with a JWT token.
Important: Save this token in your custom app—you will need it again for the Inbound flow.

In your custom app, validate the token’s key ID and signature before continuing with your business logic.

Step 4: Inbound Direction (Callback to Joule)

Follow the setup instructions in the help documentation for Joule function part:
Asynchronous API Requests

To call Joule’s callback API from the custom app, you need to perform token exchange with IAS.

Before that, let’s verify the Joule callback URL:

Go to your BTP subaccount.

Click Go to Application for Joule.

A browser window will open with “The service is up and running”.Use the displayed base URL and append: 

 /api/joule/v1/callback

Example Joule callback API: 

 https://joulefunctions-xxxxx.<region>.sapdas.cloud.sap/api/joule/v1/callback

 

Step 5: Token Exchange

Before calling the Joule callback API, perform a token exchange using this form data with your IAS token endpoint:

form_data = {
‘grant_type’: ‘urn:ietf:params:oauth:grant-type:jwt-bearer’,
‘client_id’: IAS_CLIENT_ID,
‘client_secret’: IAS_CLIENT_SECRET,
‘assertion’: <token>,
‘resource’: ‘urn:sap:identity:application:provider:name:proxy-to-joule’
}

The <token> here is the token passed along with the outbound request mentioned earlier.

 

Step 6: Final Callback and Deplooyment

After exchanging the token, call the Joule callback API with the new token.
Joule will handle the rest of the flow and display the message you defined in your Joule function.

When deploying your custom app to BTP, make sure it is bound to the CIS service you created.
Your manifest.yml should look like this:

applications:
name: <name>
path: .
memory: 256M
instances: 1
buildpacks:
python_buildpack
services:
giaIas
env:
FLASK_RUN_PORT: 8080

This ensures the app can properly communicate with IAS through the bound CIS instance.

At this point, this completes the setup of Joule’s asynchronous communication with a custom BTP application via App2App scenario.

It’s been an exciting journey to get this communication working through the App2App setup. I learned a lot of concepts along the way and am happy to share these findings with the community. If you notice anything inaccurate or have any questions, please don’t hesitate to leave a comment and I’d be glad to clarify or discuss further.

  

 

​ Today, we are going to use Joule’s asynchronous (async) feature to establish communication between Joule and a custom BTP app.Joule has a limitation when handling responses that take longer than 45 seconds, so we need to enable the async feature to properly support long-running responses.Step 1: Understand the RequirementsBefore starting, please review the help documentation:Asynchronous API RequestsThe prerequisites are critical:To enable asynchronous API requests:• IAS-enabled subaccount    o The BTP subaccount must be integrated with SAP Identity Authentication Service (IAS)• For callback support your backend has to:    o Perform the actual asynchronous task.    o Send a callback to Joule once complete.• A trust configuration must be set up between the backend system and Joule:    o This requires implementation efforts on Joule integration configuration    o To trigger this, create an AIPS requirement on the Joule component in JiraIf your account is not IAS-enabled yet, check this guide:SCI Developer Guide – IntroIf you are trying to enable the async feature of Joule on a SAP LoB product, you need to create an AIPS Jira ticket.Step 2: App2App with IASTo enable the async feature with IAS, we use the App2App approach.If you are interested, learn the concepts of Inbound and Outbound App2App for SAP DAS:InboundOutboundOnce familiar, you can start setting up trust between Joule and IAS by following:IAS App2App Dev SetupOur scenario is slightly simpler than the reference document.In the documentation, the flow is:  Joule <-> devflow_proxy_app <-> downstream app (SAP Build Workzone)Our goal is: Joule <-> custom appThis means we do not need a proxy layer in the IAS console.We can directly link Joule’s Cloud Identity Service to the custom app’s Cloud Identity Service.In my case, my custom app’s CIS is named as “giaIas”.Step 3: Configure the Destination for JouleNow, create a Destination at the subaccount level for Joule to consume.Because we do not have a middle layer for redirecting, we do not need below property in destination configuration: tokenService.body.resource=urn:sap:identity:application:provider:name:proxy-to-targetUse the following destination settings: Name=DestionationName Type=HTTP URL=<target-api-url> ProxyType=Internet Authentication=OAuth2JWTBearer clientId=<custom_app_cis-clientID> clientSecret=<custom_app_cis-clientSecret> tokenServiceURL=<ias-host>/oauth2/token x_user_token.jwks_uri=<ias-host>/oauth2/certs apptoapp=true tokenService.body.token_format=jwt tokenService.body.client_id=<custom_app-clientID>tokenService.addClientCredentialsInBody=false tokenServiceURLType=Dedicated With this configuration, the Outbound setup is complete.Joule can now send requests to this destination and forward them to your target URL with a JWT token.Important: Save this token in your custom app—you will need it again for the Inbound flow.In your custom app, validate the token’s key ID and signature before continuing with your business logic.Step 4: Inbound Direction (Callback to Joule)Follow the setup instructions in the help documentation for Joule function part:Asynchronous API RequestsTo call Joule’s callback API from the custom app, you need to perform token exchange with IAS.Before that, let’s verify the Joule callback URL:Go to your BTP subaccount.Click Go to Application for Joule.A browser window will open with “The service is up and running”.Use the displayed base URL and append:  /api/joule/v1/callbackExample Joule callback API:  https://joulefunctions-xxxxx.<region>.sapdas.cloud.sap/api/joule/v1/callback Step 5: Token ExchangeBefore calling the Joule callback API, perform a token exchange using this form data with your IAS token endpoint:form_data = { ‘grant_type’: ‘urn:ietf:params:oauth:grant-type:jwt-bearer’, ‘client_id’: IAS_CLIENT_ID, ‘client_secret’: IAS_CLIENT_SECRET, ‘assertion’: <token>, ‘resource’: ‘urn:sap:identity:application:provider:name:proxy-to-joule’ }The <token> here is the token passed along with the outbound request mentioned earlier. Step 6: Final Callback and DeplooymentAfter exchanging the token, call the Joule callback API with the new token.Joule will handle the rest of the flow and display the message you defined in your Joule function.When deploying your custom app to BTP, make sure it is bound to the CIS service you created.Your manifest.yml should look like this:applications:
– name: <name>
path: .
memory: 256M
instances: 1
buildpacks:
– python_buildpack
services:
– giaIas
env:
FLASK_RUN_PORT: 8080This ensures the app can properly communicate with IAS through the bound CIS instance.At this point, this completes the setup of Joule’s asynchronous communication with a custom BTP application via App2App scenario.It’s been an exciting journey to get this communication working through the App2App setup. I learned a lot of concepts along the way and am happy to share these findings with the community. If you notice anything inaccurate or have any questions, please don’t hesitate to leave a comment and I’d be glad to clarify or discuss further.     Read More Technology Blog Posts by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author