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.
Showing results forย 
Search instead forย 
Did you mean:ย 
Product and Topic Expert
Product and Topic Expert
Here is an end to end hands-on about using SAP Event Mesh on SAP Business Technology Platform (China, Shanghai region, or cf-cn40 landscape). You can find all the code snippets used in this blog post in this GitHub repository.

The process of renaming (from Enterprise Messaging to Event Mesh) and the rollout of the free service plan is still undergoing, and we will update this tutorial according to the latest changes.
๐Ÿ’ป Prerequisites:

  • Global Account and Subaccount on SAP Business Technology Platform (China, Shanghai Region)

  • Entitlements of SAP Event Mesh, SAP Business Application Studio


Set Up Service Instance and Subscription

First, we go to Cloud Cockpit and set up service entitlements, instances, subscriptions and user authorizations.



Assign one of each following entitlement to your Subaccount:

Service Technical Name Plan
Event Mesh enterprise-messaging default
Enterprise Messaging enterprise-messaging-hub standard

The first entitlement is to create a message client service instance, and the second one is to provide a management cockpit, or dashboard as the name given.

Service instance

In your cf space, create a service instance for Event Mesh (technical name: enterprise-messaging), with the service plan default.

In the wizard, you are asked to fill in a JSON-formatted service descriptor (following the Syntax for Service Descriptor), you can copy and paste the following, and change the parameters:

"emname": "<message-client-name>", // fill in your message client name
"namespace": "<your-namespace>", // fill in your namespace
"version": "1.1.0",
"options": {
"management": true,
"messagingrest": true,
"messaging": true
"rules": {
"queueRules": {
"publishFilter": [
"subscribeFilter": [
"topicRules": {
"publishFilter": [
"subscribeFilter": [

๐Ÿ”– Besides Cloud Cockpit, you can also do this step via CF CLI.


Service key

To create a service key, in the cockpit, select service instance ๐Ÿ‘‰ create service key ๐Ÿ‘‰ just type in the name of the service key ๐Ÿ‘‰ and hit create.

Take a look at the auto-generated JSON-formatted service key, and find the key-value pairs of:

  • namespace,

  • management API URI, and three messaging API URIs (typically the URI for HTTP REST protocol),

  • client id, client secret and token endpoint.

You will make use of them later.


Subscription and role collections

In the cockpit, subscribe to Enterprise Messaging (technical name: enterprise-messaging-hub), standard service plan.

Add role collections and assign users for the application subscription. Role collections are already created, so you can assign users, i.e. your SAP account to the collections to get access to Enterprise Messaging.

Now you can go to the application "Event Mesh Dashboard" by clicking the link provided in the subscription and have some explorations, for instance, you can go to the message clients page, and find the message client you just created when you create your service instance.


Create a queue and test the messaging via the dashboard


๐ŸŽฌ Scenario: you want to watch CCTV New Year's Gala. You are busy but you don't want to miss all the comedies. CCTV will send you messages when a performance starts, and the message will tell you if it is comedy.

You need to first create a queue named comedy. On page SAP Event Mesh Dashboard ๐Ÿ‘‰ on the left menu, select tab Message Clients ๐Ÿ‘‰ go into the tile mymessageclient ๐Ÿ‘‰ tab Queues ๐Ÿ‘‰ click Create Queue ๐Ÿ‘‰ in the pop-out window, fill in the parameters: queue name = comedy, and leave others as default.


Hit Create, and you can see the queue myorg/mymessageclient/001/category has been created, with zero messages currently.
๐Ÿ”– You don't have to add namespace as a prefix to your queue name as it will be attached.



Go to Test, on the left-hand side, select the queue and message client, fill in the Message Data parameters, hit Publish Message. You can see a "published" notification flashing out, and there is one message in the queue now.
๐Ÿ“Š Sample Message Data

  • Content-Type: application/json

  • Body: {"time": "20210124 21:00:00", "category": "music"}

On the right-hand side, select the queue and message client, and hit Consume Message. You can receive the message data you just published, and the number of messages in the queue goes down to zero.


Create a queue and send message to the queue, via messaging API (postman)

๐ŸŽฌ Scenario: your daughter also watches the show. She wants to know when she can see her idols on the screen, so she is interested in CCTV's messages about the artists screen time.

To create a queue, Event Mesh provides a type of APIs to manage the queue, queue subscription, etc., REST APIs for Management, to publish and consume messages, the type is REST APIs for Messaging.

We use Postman to send HTTP requests. Remember to find URLs and other values from the service key.


Get access token

Before communicating with Event Mesh services via APIs, we need to get the access token from XSUAA. This Help document can guide you through the process of fetching access token by providing client id and client secret to the token endpoint.

What you need to fill in the postman:

Tab Key Value
Bar Method choose GET
Bar URL <tokenendpoint>?grant_type=client_credentials&response_type=token
Authorization Type choose Basic Auth
Authorization Username <clientid>
Authorization Password <clientsecret>

Send the request, you will get 200 OK response, with the access_token. The access token needs to be included in the header of the next few requests: AuthorizationBearer {{access_token}}.


Create a queue

In the document about API, you can find the API to create queue is PUT /hub/rest/api/v1/management/messaging/queues/{queue}.

The parameter in URL: {queue} is the URL encoded queue name with a namespace prefix. e.g. myorg/mymessageclient/001/artist --> myorg%2Fmymessageclient%2F001%2Fartist.

What you need to fill in the postman:

Tab Key Value
Bar Method choose PUT
Bar URL <management[0].uri>/hub/rest/api/v1/management/messaging/queues/{queue}
Authorization Type choose No Auth
Headers Authorization Bearer <access_token>

The body is optional, schema QueueP is defined with default values.

Send the request and you will get the response of 201 Created, with the information of the created queue.

To list the queues, use GET /hub/rest/api/v1/management/messaging/queues. Instead of Method and Path, all other parameters remain the same. Send the request, you can see all the queues.


Send and consume message via message API

To send a message to a queue, we can find the API in messaging API POST /messagingrest/v1/queues/{queue-name}/messages. Parameter {queue-name} in URL again should be URL encoded full name with a namespace prefix.

Tab Key Value
Bar Method choose POST
Bar URL <messaging[protocol=httprest].uri>/messagingrest/v1/queues/{queue-name}/messages
Authorization Type choose No Auth
Headers x-qos sample 0
Headers Authorization Bearer <access_token>
Body raw - JSON sample {"time": "20210124 21:00:00", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}]}

Header x-qos is the quality of service, 0 means as long as the message is sent, mission completed; 1 means make sure the receiver get at least one message.

For Body, you can choose raw type, and type in any text, for cloud event you can have a defined JSON format.

The ID of the created message will be returned in the header of the response.

To consume a message from the queue, POST /messagingrest/v1/queues/{queue-name}/messages/consumption. Use the same header settings, and leave the body blank.

All postman config files can be found in the folder ./apis.


Create a topic, and publish messages to the topic

๐ŸŽฌ Scenario: if CCTV only sends one type of message, performance, containing the performers and category information that you and your daughter care about. to prevent that one message will be retained until you or your daughter consumes it, you two decide to maintain two personal queues. and subscribe to the performance topic, aka queue subscription.


Create a topic (queue subscription) for artist via dashboard

You can subscribe via the dashboard. Note that the queue can only subscribe to topics that follow the rules defined in the service descriptor. here it means the topic should have the same namespace prefix as the queue.


Publish messages to the topic

Send a message to the topic and you will find the queue artist receives the message.

In the postman, we use API POST /messagingrest/v1/topics/{topic-name}/messages to send the request.

Tab Key Value
Bar Method choose POST
Bar URL url encoded <messaging[protocol=httprest].uri>/messagingrest/v1/topics/{topic-name}/messages
Authorization Type choose No Auth
Headers x-qos sample 0
Headers Authorization Bearer <access_token>
Body raw - JSON sample {"time": "20210124 21:05:00", "name": "A Funny Comedy", "category": "comedy", "artists": [{"name": "Ling Jia"}], "status": "START"}

In the dashboard, you will find that the number of messages in the queue artist increases by 1.


Create queue subscription for queue category via APIs

Via management APIs, in postman, we use PUT /hub/rest/api/v1/management/messaging/queues/{queue}/subscriptions/{topic}.

Tab Key Value
Bar Method choose PUT
Bar URL URL encoded <management[0].uri>/hub/rest/api/v1/management/messaging/queues/{queue}/subscriptions/{topic}
Authorization Type choose No Auth
Headers Authorization Bearer <access_token>

Parameters in URL queue and topic they all need to be encoded with prefix. Leave the body blank.

If the topic creation successfully proceeds, the response will be 201 Created, with the names of the queue and the topic as the body.

The current architecture:

architecture: adopted from SAP Help Portal


Publish messages to the topic and consume the messages from two queues via APIs

Send a message to the topic.

Tab Key Value
Bar Method choose POST
Bar URL URL encoded <messaging[protocol=httprest].uri>/messagingrest/v1/topics/{topic-name}/messages
Authorization Type choose No Auth
Headers x-qos sample 0
Headers Authorization Bearer <access_token>
Body raw - JSON sample {"time": "20210124 21:00:00", "name": "Go, Amigo and Hi, Motherland Mash Up", "category": "music", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}], "status": "START"}

You can see both of the queues can receive the message.

Let's consume the message from the two queues.


[optional] Develop producer and consumer applications on SAP BTP

In this tutorial Tutorial: Develop a Messaging App on SAP BTP, you can learn how to develop Node.js-based and Java-based message cunsomer or producer applications on BTP.

SAP has provided full collections of development tool sets like Node.js packages, Java libraries, and other programming languages, to help you develop messaging applications logic in XS Advanced (i.e. SAP HANA Extended Application Services advanced model, the Cloud Foundry PaaS with enhancements provided by SAP)).



For development in JavaScript, you can make use of Standard Node.js Packages for XS Advanced:

  • @Sap/xb-msg: Provides messaging capabilities with a message broker. This package supports the RabbitMQ message broker with the following protocols: amqp v091, amqp v100, mqtt v311

  • @Sap/xb-msg-env: Provides the functions needed to set up messaging client options from Cloud Foundry or XS advanced environment variables

  • @Sap/xsenv: Utility for easy setup and access of XS Advanced environment variables and services



For development in Java, you can leverage SAP Cloud Application Programming Model (libraries:*), following Java Message Service (JMS) 2.0 specification, :

  • MessagingService,

  • MessagingServiceJmsConnectionFactory,

  • ...

For the SAP Cloud SDK, features of Event Mesh for both of JavaScript and Java is planned, and its progress depends on CAP.


Create a webhook (nodejs), deploy it (application studio), and subscribe your webhook to a queue

๐ŸŽฌ Scenario: now you don't want to check the queue from time to time for the comedy performances, you want to build a webhook which can send you notification when there is a performance message from the CCTV, and the performance is comedy.

Instead of consumers fetching messages from the message client, if we add a webhook, the message client will POST the messages from the specified queue to the specified URL. Here we only create a webhook for the queue comedy.

The current architecture of a webhook looks like this:

architecture with webhook: adopted from SAP Help Portal

We provide an as-simple-as-possible webhook application sample here, which is adopted from Part 1 of the series of Youtube: Diving into messaging on SAP Cloud Platform (1-8).


Create and deploy

Go to application studio ๐Ÿ‘‰ create a Full Stack Cloud Application Dev Space named emtester, go into the dev space ๐Ÿ‘‰ Create Project ๐Ÿ‘‰ select template and target location Basic Multitarget Application ๐Ÿ‘‰ Start ๐Ÿ‘‰ type in the project name webhook, finish.

Delete all the auto-created files and folders. create file manifest.yml. copy and paste the following content:
- name: webhook
- route: <host-name>.<domain>
path: .
memory: 128M

Replace the name with your app name, route with your host name concatenated with your custom domain, e.g.

If you don't know which domain you can make use of, open terminal ๐Ÿ‘‰ cf login ๐Ÿ‘‰ choose the targed org and space ๐Ÿ‘‰ cf domains ๐Ÿ‘‰ find one.

In the terminal, go to the current folder, npm init and hit return to get all the default values. type in ok. You will find the file package.json is created, and it requires a main page index.js.

Install the two Node.js packages we will use, express and body-parser, by npm install express body-parser
๐Ÿ”– What do these two packages do?

express is a Node.js package to provide small, robust tooling for HTTP servers, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs.

body-parser is a Node.js package to parse incoming request bodies in a middleware before your handlers, available under the req.body property.

We want to add start script, so add key-value pair start in the scripts, and delete the test from the scripts. Finally the file package.json will look like:
"name": "webhook",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"

Now let's work on the file index.js, just create it and copy and paste:
const express = require("express")
const bodyParser = require("body-parser")

const app = express()
const PORT = process.env.PORT || 8080


app.get('/', (req, res) => {
res.status(401).send('Hey, this is a webhook - we only receive POST!')
})'/', (req, res) => {
if(req.body.category == "comedy") {
console.log(' ', req.body)
res.status(200).send(' ' +
else {
console.log(' ', req.body)

app.listen(PORT, () => console.log(` Server running on port ${PORT}`))

[Optional] If you want to test the app in local terminal, go to the project root, run npm start, and in a new tab use curl to send request to localhost:
curl -H 'Content-Type: application/json' -d'{"time": "20210124 21:00:00", "name": "Go, Amigo and Hi, Motherland Mash Up", "category": "music", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}], "status": "START"}' http://localhost:8080/

curl -H 'Content-Type: application/json' -d'{"time": "20210124 21:05:00", "name": "A Funny Comedy", "category": "comedy", "artists": [{"name": "Ling Jia"}], "status": "START"}' http://localhost:8080/

The first request will leave a log with sad face, and the second request will make the webhook app to log a happy face.

Deploy it onto BTP. In the terminal, go to project root, run cf push.

Test the webhook by sending a message to the webhook with the postman (or curl from the terminal).

All the code snippets can be found in the folder ./webhook/.


Create webhook subscription

Go to dashboard ๐Ÿ‘‰ go into our message client ๐Ÿ‘‰ choose webhooks tab ๐Ÿ‘‰ creat webhook subscription ๐Ÿ‘‰ in the pop-up window, fill in queue name, webhook url and other parameters ๐Ÿ‘‰ click create.

The process of activation will be completed by making a handshake between the message client and your webhook application, during the first message exchange.


Send a message to the topic performance, and read the logs of the webhook application webhook

Then publish a message to the topic performance again. You will find, artist queue has lined up with messages to be consumed, while category queue has zero messages. It is because the messages to the latter queue have been forwarded to the webhook.

Go to cf logs webhook to see the logs, you will find that all the two messages have been logged, labelled with an interested or not interested label.

If you bind the SAP Application Logging Service to your webhook application (here is the How-To on SAP Help Portal), you can also observe the logs on the cockpit.



In this blog post, we first set up SAP Event Mesh service instance and subscription on Cloud Cockpit. Then, we tried to create queues via SAP Event Mesh Dashboard and HTTP API calls, and we tested the messaging of the queues by publishing messages to the queues and consuming the messages. We also created a queue subscription and tested it by publishing messages to the topic and consume them from the queues. Next, we build a webhook, deployed it to the BTP CF environment, and subscribe it to one of the queues. By now, you have walked through a full end-to-end scenario of SAP Event Mesh on cn40.

If you have further questions, feel free to leave me a comment here, or submit a question in the Q&A area on this topic.