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: 
schardosin
Explorer
Cloud Application Programming (CAP) is an excellent development framework if you are working with the SAP Business Technology Platform (SAP BTP), it provides you an easy way to create your data domain models and expose them as OData Services, which will use Hana Database as the persistence layer. All of this is done in an easy way, which requires minimal configuration.

But CAP is more than that, it has the goal to provide a framework that will allow you to consume other SAP BTP services in a seamless way, and providing you the best practices when using these services.

One of the additional capabilities of SAP CAP is to easily integrate with SAP Event Mesh, there are lots of blogs that show how to configure to be able to emit to and receive messages from SAP Event Mesh, it requires simple configuration and a bind between the SAP Event Mesh service and your application.

But this post has the goal to present when you cannot use the standard implementation from CAP to consume messages from SAP Event Mesh.

CAP by convention creates a single queue, which is in the format of CAP/0000 or {Application_name}/{4 digits of application_id}, to consume the topic you inform in the handler, handlers don't handle queues directly, you need to specify a topic on it.

messaging.on('my/em/namespace/topic', async (msg) => { ... }

If you start specifying multiple handlers to consume multiple topics, it will consume the queues as expected by subscribing all these topics to the queue CAP/0000, CAP can distinguish when it receives a message in a queue, what is the topic associated with the message, and then it delivers to the right handler.

The "problem" is when you already have a queue to be consumed, for any reason you had to create it manually, for example, to configure a dead queue or any other configuration not supported by CAP for a queue.

In the configuration file (package.json) you can set which queue must be used by each messaging client, in this format:
{
cds: {
requires: {
messaging1: {
kind: 'enterprise-messaging-shared',
queue: {
name: 'my/em/namespace/my/queue/one'
}
},
messaging2: {
kind: 'enterprise-messaging-shared',
queue: {
name: 'my/em/namespace/my/queue/two'
}
}
}
}
}


with this configuration, when you create your client, it knows what queue name it must use.

const messaging = await cds.connect.to('messaging1')

The implementation above knows it must use the already created queue my/em/namespace/my/queue/one.

Easy solution, right? Well, be cautious with that!

CAP always expects a message in a queue to have a topic associated with it, in case you start consuming queues that contain messages not associated with topics, the message will be consumed by CAP, but it will not be delivered to any handler, once handlers ALWAYS expect a topic.

A good example of these scenarios are the dead queues, once a message reaches the max retry and is sent to a dead queue, this message will not be associated with a topic in the dead queue, and by consequence, CAP will not be able to consume it. So for dead queues, expects to use the @Sap/xb-msg-amqp-v100 manually to consume it (in case of node.js).

Hope this helps!

15 Comments