Technical Articles
SAP Cloud Application Programming Model and Enterprise Messaging [4]: Local Development
With other words:
How to
develop locally with
CAP
and
Enterprise Messaging
Quicklinks:
Intro Blog
Local + Remote
Local + Local
One of the first features which users appreciate at CAP is the optimized local development.
However, if we do a cds run to start our apps, developed in previous tutorials, locally, then we get an error. Obviously, because we don’t have the Enterprise Messaging on our local file system.
As such, we need to install it locally.
This blogs explains how to install the cloud locally.
…Which is of course nonsense
This blog explains how to work locally with CAP application – even with Enterprise Messaging remaining in the cloud.
It is possible, because it is possible to use the network
So even from local machine, CAP can still connect to Enterprise Messaging in the SAP Cloud Platform
No code modifications required.
It works both with Trial and productive landscape
This blog is part of a little series explaining how to use SAP Cloud Platform Enterprise Messaging with CAP (SAP Cloud Application Programming Model) application
Prerequisites
For this blog, I’m re-using the application created in Tutorial 2 and tutorial 3
However, you can use any messaging-enabled CAP application
Local Development with Remote Messaging
In this scenario we want to start our server locally and avoid deploying our app to the SAP Cloud Platform.
Nevertheless, we want to use the Enterprise Messaging instance which we created in the Cloud.
For example, our receiver app should get notified of messages which are sent to the broker in the cloud (e.g. by S/HANA Cloud)
That should work:
My local app should receive messages that a remote system sends to the Enterprise Messaging in the cloud
How does it work?
It is possible to connect to the broker from anywhere if the client knows the URL and the credentials
CAP supports it by reading the credentials etc from a local config file
As such, we only need to provide that required file filled with the required data in the required way
These are the required steps:
Step 1:
In your CAP project, create a file with name default-env.json in the project root folder
The project root folder is the one which contains the package.json file
Step 2:
Deploy your app to the cloud
This is required only once
Step 3:
After deployment, check the environment variables.
In the cockpit, you can click into the field “System-Provided” and use Ctrl+A
Or in command line:
cf env receiverapp
Copy all the env to clipboard
Step 4:
Paste the copied JSON into the default-env.json file created above
Step 5:
This step is little bit disappointing…
We have to realize:
The copyandpasted json is invalid….
See the error in the editor:
We need to have a detailed look:
In the env, there are 2 consecutive json objects
Like this:
{
"VCAP_SERVICES": {
}
}
{
"VCAP_APPLICATION": {
}
}
You see: there are no top-level brackets embracing all the content.
That’s why the error message complains about the next opening bracket
We need to repair it:
-> remove the closing bracket of the first json object
-> add a comma
-> remove the opening bracket of the second json object
Result should look like this:
{
"VCAP_SERVICES": {
}
,
"VCAP_APPLICATION": {
}
}
Right?
Can be more beautiful, of course
That’s it
Note:
In our example, we have only one service binding. As such we can copy all, including the VCAP_APPLICATION section
That makes 2 json object and we can repair like described above
If you have more bindings in your application, it might take more effort to repair the json
Note:
CAP doesn’t really require the complete data of the env
E.g. from the application env, only the name is needed (for generating queue name)
However, it doesn’t make a difference for us, we can just leave the json, once it is repaired
Test it
For testing this scenario I’m using the receiver application created in tutorial 3
To test the local development with remote messaging, we only need to start the CAP application locally with the well-known
cds run
If we don’t receive an error … then it has worked
If you want to see a proof:
Go to your messaging dashboard (as explained here)
Here you can delete your queue
Reason: you want to see how it is re-created by local CAP application
Alternatively:
If you don’t want to delete a queue, you can let your local CAP application generate a new queue
You only need to change the application name in the default-env.json file
Open your local default-env.json -file and find the VCAP_APPLICATION section and find the property application_name
Here you can change the value to anything silly
"VCAP_APPLICATION": {
"application_name": "capappsapapp"
Note:
This works only for CAP apps which consume messages and have an messaging handler defined in the custom handler
Only in those cases, CAP generates queues
Sender applications need to be tested with sending messages, starting the app is not enough
Stop your app and start it again
Then check the messaging dashboard (refresh):
There you can see the newly generated queue
I bet my bed that you will use this local development option day and night from now on…
What has been done under the hood?
The Enterprise Messaging offers a REST API which allows to programmatically manage queues and subscriptions.
CAP reads the environment variables from the default-env.json file
It uses the URL and clientid etc to fetch a JWT token from the OAuth server URL
Then it uses the JWT token to create queue and subscription with corresponding POST requests
Really local development with really local messaging
This scenario is useful in case you’re one of those totally addicted CAP developers …. who desire to continue hacking e.g. on a flight to Caribbean beach,in offline mode … (where the non-addicted wouldn’t even think of carrying a laptop..)
OK, for such incurable cases, CAP supports an offline messaging scenario:
CAP can send messages to a file instead to a topic (similar for reading)
For such scenario, you need to change the messaging configuration in package.json file
Replace enterprise-messaging with file-based-messaging
"cds": {
"requires": {
"messaging": {
"kind": "file-based-messaging"
}
}
},
Test it
For testing, I’m using the sample “sender” application from tutorial 2
Start your application locally with cds run
Trigger the send() function import to send messages
In the console you can see the interesting output:
GET /sender/send()
[cds] – mocking Messaging using file: C:\Users\joecool\AppData\Local\Temp\cds-message-box
As we know, when sending a message to a broker and there’s no subscribed consumer, then the message will stay in the queue.
As such, we can go to the mentioned directory and have a look at the “cds-message-box”
And there we are: the messages are there
Summary
In this blog we’ve learned how to speed up the CAP app development via local configuration
We’ve learned there are 2 flavors of local development with messaging:
* Connecting to remote broker using the broker-credentials stored in default-env.json file
* Using local file which serves like a messaging queue
I hope this has been useful for you
Troubleshooting
If you have headache because messages aren’t arriving in Messaging Queue, you should check this guide
Links
Blog Series:
Intro Blog: CAP and Enterprise Messaging
First Blog: create CAP application to send messages to Enterprise Messaging
Second: create CAP application to receive messages
CAP managed messaging using keyword “event” in CDS model
Hi Carlos Roggan
I’m following your great blog posts here and to start with just wish to have local messaging working on my laptop with
cds watch
.I have added :
… and when I type
cd watch
I see a message: “[cds] – connect to messaging > file-based-messaging { file: ‘~/.cds-msg-box’ }” – so far so good.Now in my service I send a test message. I receive no error but also there is no message published into the local messaging file.
Is there something missing? Do I also need to create the default-env.json file (my understanding was that this is only necessary if I want to connect to a real enterprise messaging instance)?